2014-03-12 118 views
2

这怎么可能:Scala类型推断失败?

import scala.util.{Try, Success} 
import reflect._ 

case class Foo[A](x: A) extends Dynamic { 

    def get[T: ClassTag]: Option[T] = Try(x.asInstanceOf[T]) match { 
    case Success(r) => Some(r) 
    case _ => None 
    } 
} 

object Foo extends App { 
    val test = Foo("hi") 
    val wtf: Option[Int] = test.get[Int] 
    assert(wtf.isInstanceOf[Option[String]]) 
    assert(wtf == Some("hi"))  // how???? 
    // val wtf2: Option[String] = wtf // does not compile even if above assert passes!! 
} 

灵感来自这个问题:Scala check type of generics

回答

1
  1. 由于类型擦除,wtf.isInstanceOf[Option[String]]只能检查wtfOption一个实例,而不是类型参数。同样,asInstanceOf[T]实际上是在运行时转换为Object,因此它成功。您需要做

    classTag[T].runtimeClass.cast(x) 
    

    改为。

  2. 编译器不能使用这些信息从传递断言(你能想象一个编译器,可能,但斯卡拉根本没有设计这样的)。它只知道wtf的类型是Option[Int],所以当然你不能用它初始化Option[String]。如果你想获得类似的东西,你需要

    wtf match { 
        case wtf2: Option[String] => ... 
    } 
    

    当然,这并不正确,由于点工作1