这怎么可能:
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
答案 0 :(得分:1)
由于类型擦除,wtf.isInstanceOf[Option[String]]
只能检查wtf
是Option
的实例,而不是类型参数。类似地,asInstanceOf[T]
实际上是在运行时转换为Object
,因此它成功。你需要做
classTag[T].runtimeClass.cast(x)
代替。
编译器无法使用断言传递的信息(你可以想象可能的编译器,但Scala根本就不是这样设计的)。它只知道wtf
的类型为Option[Int]
,因此您无法使用Option[String]
初始化wtf match {
case wtf2: Option[String] => ...
}
。如果你想得到类似的东西,你需要
{{1}}
当然,由于第1点,这种方式无法正常工作。