[scala] Pattern matching / Type matching

Programming/scala 2015.04.08 14:03

스칼라를 쓰면서 이해하는데 많은 공이 들어가는게 matching이다.


매칭을 쓰다가 괴팍한 문제에 부닥혔다.

type matching을 이용하여 case문을 쓰려고 한 코드다.

val t = ("string", Int)


t match {

case t:(String, String) => println("second value is string")

case t:(String, Int) => println("second value is int")

case _ => println("others.")

}


이렇게 하면 두번째 매칭인 (String,Int)에 매칭이되어 "second value is int"가  나와야 할것 같은데.. 첫번째인 "second value is string" 가 나온다.

그러면서 워닝이 뜨지.

<console>:10: warning: fruitless type test: a value of type (String, Int) cannot also be a (String, String) (but still might match its erasure)

              case t:(String, String) => println("second value is string")

                     ^

<console>:11: warning: unreachable code

              case t:(String, Int) => println("second value is int")

이는 튜플의 제네릭 타입 추론이 불가능해서 인걸로 추측이 되는데..

t match ...  요부분에서 t의 타입을 정해주지 않았기에 컴파일러가 튜플 내의 타입을 추론하지 못한것 같다.

만약에 tuple이 val t = ("string", 0) 이렇게 되어있다면

아래와 같은 type matching이 가능하다.

(t: (Any, Any))  match {

  case (t1: String, t2: String) => "this is string"

  case (t1: String, t2: Int) => "this is int"

  case _ => "this is other!"

}

왠지 위의 코드로 원래의 문제였던 val t = ("string", Int)를 넣으면 제대로 매칭할 것 같지만.. 실제로 돌려보면 아니다...

실제로 돌려보면 아무것도 매칭되지 않아서 "this is other!"가 출력된다.


이를통해서 하나의 tuple내에서 type matching과 pattern matching이 병합적으로 사용되지 못함을 알 수 있다.

Int의 type은 Int가 아니고 object scala.Int이기 때문이다.


결국은 type matching으로 해결하기 힘들게 되어 나온코드는 pattern matching을 사용하는 코드였다.

val t = ("string", Int)

t._2 match {

case Float => "this is Float"

case Int => "this is Integer"

case _ => "this is other!"

}


두번째 인자인 Int == Int 이기 때문이다.

하지만 이것도 근본적인 해결책은 아니다. 왜냐하면

val t = ("string", "string val") 형태로 들어온것을 잡아내기 위해서는 

case "string val" 이라고 명시되어야 하기 때문이다.

case String 이라고 쓸수 없으니까...

결국 제일 마지막의 _ 에 걸릴수 밖에 없다.





저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License


티스토리 툴바