2013-09-04 4 views
3
object Test { 
    def main(args: Array[String]) { 
    val list: List[Double] = List(1.0, 2.0, 3.0, 4.0) 
    val none = None 

    case class Test() 

    val test = Test() 

    def f(x: Any) = x match { 
     case _: Some[Test] => println("_ matched") 
     case None => println("None matched") 
    } 

    f(list) 
    f(none) 
    f(test) 
    } 
} 

위의 코드를 컴파일하려고하면 "지워짐에 의한 제거"컴파일 타임 경고가 발생합니다. 스칼라 유형 지우기 옵션 일치

$>scalac Test.scala 
    Test.scala:11: warning: non-variable type argument Test in type pattern 
Some[Test] is unchecked since it is eliminated by erasure 
      case _: Some[Test] => println("_ matched") 
        ^
    one warning found 

나는이 높은 평가를 받고 유래 post를 읽을 수 있지만 여기 유형의 삭제를 이해하지 않습니다.

답변

7

런타임에 jvm에는 만있는 또는 Some[String]이 없습니다. 따라서 Some[Test]에 일치시킬 수 없습니다. 왜`instanceof` 불쾌한 생각된다

case Some(e: Test) => println(s"$e matched") 
+0

그래서 런타임시 JVM은 Some (Int)와 Some (String)의 차이를 알지 못하지만 Some (x)에서 x의'type'을 찾을 수 있습니까? –

+3

@Kevin : 네, 다른 변수 유형과 같습니다. 스칼라 컴파일러는'case Some (e : Test)'를'if (arg.isInstanceOf [Some [_]] && arg.asInstanceOf [Some [Any]]. get.isInstanceOf [Test])와 같은 것으로 재 작성합니다. .asInstanceOf [일부 [모두]]. get.asInstanceOf [테스트] ...}'. – senia

9

런타임에 값이 Some[Test]이고 Some[Int] 또는 Some[anything else]이 아닌지 확인할 방법이 없다는 경고입니다. 이는 JVM이 유형 매개 변수에 대해 알지 못하기 때문입니다 (즉, Java에서 유형 삭제가있는 것과 같은 이유). 참조하는 게시물은이 유형의 삭제 문제를 해결하기 위해 스칼라에서 제공되는 방법을 보여줍니다. Some[Test]을 갖고 다른 일부 하위 유형이 아닌지 확인해야합니다. 귀하의 경우에는 관련성이없는 것처럼 보이므로 경고를 흘리지는 않을 것입니다. (!하고 실용적인) 더 관용적 한편

은 다음과 같습니다

def f(x: Any) = x match { 
    case Some(y) => println(s"x matched to Some - wrapped value is $y") 
    case None => println("None matched") 
} 

Some[Any]에 일치하지만이 경우 블록 내부에 직접 사용할 수 있도록 또한 래핑 된 가치를 제공합니다.

값이 Test 유형인지 확인해야하는 경우 TypeTags (예 : 언급 한 링크 또는 here 참조) 주위에 머리를 감싸 주거나 다소 불쾌한 isInstanceOf 메소드를 사용하십시오.

case Some(y) if (y.isInstanceOf[Test]) => ... 

편집 : 또는

@의 니아의 대답에 따라
case Some(e: Test) => ... 

.

+0

:이 같은 Some의 내용과 일치 할 수이 경우

? –

+3

@Kevin : 만약'y'를'Test'의 인스턴스로 사용하고 싶다면'isInstanceOf'를 사용하고 있는지 확인한 다음'asInstanceOf'를 사용하여'Test'에 던지십시오. 자세한 내용입니다. 그리고'asInstanceOf'는 타입 안전하지 않습니다 : 컴파일러는'asInstanceOf' 전에'isInstanceOf'를 사용하도록 강제하지 않을 것입니다. 구조 패턴 일치는 유형에 안전합니다. 위험한 작업을하는 경우 경고 메시지가 표시됩니다. – senia