투명한 기부를 하고싶다면 이 링크로 와보세요! 🥰 (클릭!)
바이낸스(₿) 수수료 평생 20% 할인받는 링크로 가입하기! 🔥 (클릭!)
Programming in scala 를 참고하여 작성했음을 밝힘니다.
케이스 클래스는 다음과 같이 정의할 수 있다.
abstract class Expr // trait가 되어도 괜찮아~
case class Var(name: String) extends Expr
case class Number(num : Double) extends Expr
case class UnOp(operator:String, arg:Expr) extends Expr
case class BinOp(operator:String, left: Expr, right: Expr) extends Expr
case수식자는 스칼라 컴파일러에게 해당 클래스에 문법적으로 편리한 기능 몇 가지를 추가하라고 지시하는 것이다.
1. 컴파일러는 클래스 이름과 같은 이름의 팩토리 메소드를 추가한다.
new Var("x") 대신에 그냥 아래와 같이 선언이 가능하다.
val v = Var("x")
이는 아래와 같이 중첩하여 객체를 생성할 때 특히 좋다.
val op = BinOp("+",Number(1),v)
2. 케이스 클래스의 파라미터 목록에 있는 모든 인자에 암시적으로 val 접두사를 붙인다는 것이다. 그래서 각 파라미터가 클래스의 필드가 된다. 예를 들어 op.left 는 Expr 타입의 Number(1.0) 이 된다.
3. 컴파일러는 케이스 클래스에 toString, hashCode, equals메서드의 '일반적인' 구현을 추가한다. 이런 메소드들은 케이스 클래스와 그것의 모든 인자를 (재귀적으로 구성되는)하나의 온전한 트리로 보고 그것을 문자열로 만들거나 해시를 계산하거나 비교한다. 스칼라에서는 ==를 사용한 비교를 항상 equals메소드에 위임하기 때문에 이는 케이스 클래스들의 원소들을 항상 구조적으로 서로 비교한다는 뜻이다.
예를 들어, 다음과 같이 비교가 가능히다.
op.right == Var("x")
op == BinOp("+",Number(1),Var("x"))
등
4. 컴파일러는 어떤 케이스 클래스에서 일부를 변경한 복사본을 생성하는 copy메소드를 추가한다. 이 메소드는 기존의 인스턴스에서 하나 이상의 속성을 바꾼 새로운 인스턴스를 생성할 때 매우 유용하다. 예를 들어, 다음과 같이 활용할 수 있다.
op.copy(operator = "-")
그 결과는
BinOp(-,Number(1.0),Var(x))가 된다.
패턴 매치
패턴 매치에서 생성자 패턴은 큰 위력을 발휘한다.
expr match {
case BinOp("+", e, Number(0)) => println("모든 원소를 다 검사해여")
case _ =>
}
이런 느낌의 패턴 매치가 가능하다. 모든 원소를 검사한다.
* 번외 :
List의 패턴 매치 활용 예시
expr match {
case List(0, _, _) => // 첫 원소가 0이고 두번째 세번째 원소는 don't care하는 리스트를 찾는다.
case List(0, _*) => // 첫 원소가 0이고 그 이후로는 길이에 상관없이 매치한다.
}
// 그냥 책에서 보는데 유용해서 넣어봤다.
타입 지정 패턴
def generalSize(x:Any) = x match {
case s : String => s.length
case m : Map[_,_] => m.size
case _ => -1
}
요로코롬 타입을 정해서 타입에 따른 매치도 가능하다 굿굿 ㅋ_ㅋ