관리 메뉴

HAMA 블로그

스칼라 강좌 (17) - case class 본문

Scala

스칼라 강좌 (17) - case class

[하마] 이승현 (wowlsh93@gmail.com) 2016. 8. 6. 18:17

case class


case 클래스 예제 

abstract class Expr

case class Var(Name: String) extends Expr

case class Number(num: Double) extends Expr 

case class BinOp(operator: String, left:Expr , right:Expr) extends Expr


* 스칼라에서 클래스 본문이 비어 있으면 중괄호를 생략할 수 있다. 


case 클래스 특징 


* 컴파일러는  클래스 이름과 같은 이름의 팩토리 메소드를 추가한다.

new Number(3.0) 대신해서 Number(3.0) 가능하다.

* 케이스 클래스의 파라미터의 목록을 val 접두사를 붙인다. 

val n = Number(3.0) 

n.num // 3.0 

* toString, hashCode,equals 메소드들의 자동으로 추가된다. 

val v = Var("x") 

val op = BindOp("+", Number(1), v) 

op.right == Var("x") // true 

* 컴파일러는 케이스 클래스에서 일부를 변경한 복사본을 생성하는 copy 메소드를 추가한다. 

    operator 만 바꾸고 op 같은 연산자를 만드는 법 

    op.copy(operator = "-")   // BindOp = BindOp(-, Number(1.0), Var(x)) 


패턴 매치

    * switch { case } 가 스칼라에서는 셀렉터 match { case }  와 같다.

    * 스칼라의 match 는 표현식이다.

    * 스칼라의 case 는 다음 case 로 fall through 하지 않는다.

    * 매치에 성공하지 않는 경우 MatchError 예외가 발생한다. 따라서 디폴트 케이스를 반드시 추가해야한다. 


    expr match {

case BinOp ( op, left, right) =>

println( ... ) 

case _ =>

    }


와일드 카드 패턴  
  expr match {
    case BinOp(op, left, right) =>
      println(expr +"is a binary operation")
    case _ =>
  }
 expr match {
    case BinOp(_, _, _) => println(expr +"is a binary operation")
    case _ => println("It's something else")
  }

상수  패턴  

 def describe(x: Any) = x match {
      case 5 => "five"
      case true => "truth"
      case "hello" => "hi!"
      case Nil => "the empty list"
      case _ => "something else"
    }
 scala> describe(5)
  res5: java.lang.String = five
  
scala> describe(true) res6: java.lang.String = truth
scala> describe("hello") res7: java.lang.String = hi!
scala> describe(Nil) res8: java.lang.String = the empty list
scala> describe(List(1,2,3)) res9: java.lang.String = something else

변수 패턴 

expr match {
      case 0 => "zero"
      case somethingElse => "not zero: "+ somethingElse
    }
 scala> import Math.{E, Pi}
  import Math.{E, Pi}
  
scala> E match {          case Pi => "strange math? Pi = "Pi          case _ => "OK"        } res10: java.lang.String = OK
 scala> val pi = Math.Pi
  pi: Double = 3.141592653589793
  
scala> E match {          case pi => "strange math? Pi = "+ pi        } res11: java.lang.String = strange math? Pi = 2.7182818...
 scala> E match {
           case pi => "strange math? Pi = "+ pi
           case _ => "OK"  
         }
  <console>:9: error: unreachable code
           case _ => "OK"  
                     ^
 scala> E match {
           case `pi` => "strange math? Pi = "+ pi
           case _ => "OK"
         }
  res13: java.lang.String = OK

생성자 패턴 

expr match {
      case BinOp("+", e, Number(0)) => println("a deep match")
      case _ =>
    }

시퀀스 패턴 

 expr match {
      case List(0, _, _) => println("found it")
      case _ =>
    }
  expr match {
      case List(0, _*) => println("found it")
      case _ =>
    }

튜플 패턴 

def tupleDemo(expr: Any) =
      expr match {
        case (a, b, c)  =>  println("matched "+ a + b + c)
        case _ =>
      }

타입지정 패턴 

def generalSize(x: Any) = x match {
      case s: String => s.length
      case m: Map[_, _] => m.size
      case _ => -1
    }
Listing 15.11 - A pattern match with typed patterns.

Here are a few examples of using the generalSize method in the interpreter:

  scala> generalSize("abc")
  res14: Int = 3
  
scala> generalSize(Map(1 -> 'a'2 -> 'b')) res15: Int = 2
scala> generalSize(Math.Pi) res16: Int = -1

Sealed class

  sealed abstract class Expr
    case class Var(name: Stringextends Expr
    case class Number(num: Doubleextends Expr
    case class UnOp(operator: String, arg: Exprextends Expr
    case class BinOp(operator: String, 
        left: Expr, right: Exprextends Expr
Listing 15.16 - A sealed hierarchy of case classes.

Now define a pattern match where some of the possible cases are left out:

  def describe(e: Expr): String = e match {
    case Number(_) => "a number"
    case Var(_)    => "a variable"
  }

You will get a compiler warning like the following:

  warning: match is not exhaustive!
  missing combination           UnOp
  missing combination          BinOp


Comments