2021년 4월 23일 금요일

[ Scala ] Case Class에 대하여

 

스칼라는 케이스 클래스 개념을 지원하는데 특징은 아래와 같다.

  • 불변
  • 패턴매칭을 통해 분해가능
  • 레퍼런스가 아닌 구조적인 동등성으로 비교
  • 초기화와 운영이 간결


예제

Notification.scala이라는 case class스칼라 파일을 생성

abstract class Notification
case class Email(sourceEmail: String, title: String, body: String) extends Notifica
case class SMS(sourceNumber: String, message: String) extends Notification
case class VoiceRecording(contactName: String, link: String) extends Notification


클래스 Email, SMS, VoiceRecording은 일반적인 클래스와 다르다.

1. 

인스턴스를 생성할 때 NEW 키워드 생략가능. 

Ex)

val emailFromJohn = Email("doe@mail.com", "Greetings!", "Hello World!")


2. 

생성자 파라미터들에 대한 getter함수가 자동으로 정의. 

public값으로 다뤄지며 직접 접근가능 

Ex)

val title = emailFromJohn.title println(title) // prints "Greetings From John!"


3.

케이스클래스 필드 수정 불가능

Ex)

emailFromJohn.title = "Goodbye From John!"

// 컴파일시에 에러가 난다. 모든 케이스 클래스 필드는 기본적으로 val이다.

// var을 사용하여 변경할 수 있지만, 권장하지 않는다.


4.

클래스 복사가 가능하며 필드값을 대체할 수도 있다.

Ex)

val editedEmail =
emailFromJohn.copy(title = "I am learning Scala!", body = "It's so cool!")

println(emailFromJohn)
// prints "Email(john.doe@mail.com,Greetings From John!,Hello World)"

println(editedEmail)
// prints "Email(john.doe@mail.com,I am learning Scala,It's so cool!)"


5.

모든 케이스클래스에 대해 equals 메서드와 toString메서드를 생성

Ex)

val firstSms = SMS("12345", "Hello!") val secondSms = SMS("12345", "Hello!") if (firstSms == secondSms) { println("They are equal!") } println("SMS is: " + firstSms)


6.

케이스클래스를 통해 데이터와 함께 동작하는 패턴매칭 사용가능

object Test {

def showNotification(notification: Notification): String = {
notification match {
case Email(email, title, _) =>
"You got an email from " + email + " with title: " + title
case SMS(number, message) =>
"You got an SMS from " + number + "! Message: " + message
case VoiceRecording(name, link) =>
"you received a Voice Recording from " + name + "! Click the link to hear it: " + link
}
}

def main(args: Array[String]): Unit = {
val someSms = SMS("12345", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")

println(showNotification(someSms))
println(showNotification(someVoiceRecording))
}
}


// prints: // You got an SMS from 12345! Message: Are you there? // you received a Voice Recording from Tom! Click the link to hear it: voicerecording.org/id/123


7.

패턴매칭 if를 통한 다른 예제

object Test {

def showNotification(notification: Notification): String = {
notification match {
case Email(email, title, _) =>
"You got an email from " + email + " with title: " + title
case SMS(number, message) =>
"You got an SMS from " + number + "! Message: " + message
case VoiceRecording(name, link) =>
"you received a Voice Recording from " + name + "! Click the link to hear it: " + link
}
}

def showNotificationSpecial(notification: Notification, specialEmail: String, specialNumber: String): String = {
notification match {
case Email(email, _, _) if email == specialEmail =>
"You got an email from special someone!"
case SMS(number, _) if number == specialNumber =>
"You got an SMS from special someone!"
case other =>
showNotification(other) // nothing special, delegate to our original showNotification function
}
}

def main(args: Array[String]): Unit = {
val SPECIAL_NUMBER = "55555"
val SPECIAL_EMAIL = "jane@mail.com"
val someSms = SMS("12345", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
val specialEmail = Email("jane@mail.com", "Drinks tonight?", "I'm free after 5!")
val specialSms = SMS("55555", "I'm here! Where are you?")

println(showNotificationSpecial(someSms, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(someVoiceRecording, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(specialEmail, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(specialSms, SPECIAL_EMAIL, SPECIAL_NUMBER))
}
}



참조 : 

https://docs.scala-lang.org/ko/tutorials/scala-for-java-programmers.html

https://docs.scala-lang.org/ko/tour/case-classes.html

댓글 없음:

댓글 쓰기