본문 바로가기

Programmer Jinyo/Scala & FP

Scala CaseClass에 대한 특징 정리


투명한 기부를 하고싶다면 이 링크로 와보세요! 🥰 (클릭!)

바이낸스(₿) 수수료 평생 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

}

요로코롬 타입을 정해서 타입에 따른 매치도 가능하다 굿굿 ㅋ_ㅋ