【问题标题】:Scala type inference fail?Scala 类型推断失败?
【发布时间】:2014-03-12 05:47:56
【问题描述】:

这怎么可能:

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

【问题讨论】:

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


    【解决方案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 点,这不能正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 2017-06-22
      • 1970-01-01
      • 2018-08-21
      • 2020-12-30
      相关资源
      最近更新 更多