Scala类型推断失败?

时间:2014-03-12 05:47:56

标签: scala generics type-inference scala-2.10 type-erasure

这怎么可能:

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 个答案:

答案 0 :(得分:1)

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

    classTag[T].runtimeClass.cast(x)
    

    代替。

  2. 编译器无法使用断言传递的信息(你可以想象可能的编译器,但Scala根本就不是这样设计的)。它只知道wtf的类型为Option[Int],因此您无法使用Option[String]初始化wtf match { case wtf2: Option[String] => ... } 。如果你想得到类似的东西,你需要

    {{1}}

    当然,由于第1点,这种方式无法正常工作。

相关问题