[Scala] 관련있는 데이터를 묶어서 사용하기 - alias와 case class
Scala에서 여러 개의 값을 묶어서 새로운 타입을 정의하는 방법은 여러 가지가 있다.
Type alias
가장 쉬운 방법은 Tuple
의 alias를 만드는 것이다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Address = (String, Int) | |
val address: Address = ("localhost", 80) // address : ("localhost", 80) | |
val (hostname, port): Address = address // hostname : "localhost, port : 80 |
위의 코드의 4번째 줄에서 month와 date를 선언하면서 Date
타입의 변수를 쪼개 새로운 값에 할당하는 것을 decomposition이라고 한다. 이렇게 decomposition을 이용하면 구조체의 값들을 쉽게 다른 값에 할당할 수 있고, 혹은 아래와 같이 패턴매칭을 이용해서 사용할 수 있다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
address match { | |
case (hostname, port) => s"$hostname:$port" | |
case _ => "" | |
} |
하지만 튜플의 alias를 만드는 방식은 큰 문제가 있다. 이런 방식은 타입 세이프 하지 않다. 예를 들어 위에서 정의한 Address
타입과 함께 아래와 같이 정의된 Date
타입이 같이 사용된다면 둘 다 실제로는 같은 Tuple2[String, Int]
타입이기 때문에 패턴매칭으로는 Address
와 Date
를 구분할 방법이 없다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Date = (String, Int) | |
val date: Date = ("February", 21) // date : ("February", 21) | |
val (month, day): Date = day // month : "February, day : 21 |
case class
튜플의 alias가 타입 세이프 하지 않다는 문제를 해결하기 때문에 보통은 data composition에 case class
를 사용한다. case class
를 사용하면, 실제로는 다른 같은 타입들의 묶음과 구분할 수 있을 뿐 아니라, 내부 값에 이름으로 접근해 꺼낼 수 있어서 내부 값을 더 쉽게 읽을 수도 있다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Address(address: String, port: Int) | |
val address: Address = Address("localhost", 80) // address : ("localhost", 80) | |
val Address(hostname, port) = address // hostname : "localhost, port : 80 | |
// or | |
val hostname = address.hostname | |
val port = address.port | |
case class Date(month: String, day: Int) | |
val date: Date = Date("February", 21) // date : ("February", 21) | |
val Date(month, day) = date // month : "February, day : 21 | |
val x: AnyRef = date | |
x match { | |
case Address(h, p) => s"$h:$p" | |
case Date(m, d) => s"$m $d" | |
case _ => s"$x" | |
} |
댓글
댓글 쓰기