2014-03-12 139 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