2015-04-01 35 views
4

asInstanceOf[T]作品「簡單」的情況下型T由代碼明確給出:例如如何給一個變量轉換爲特定的運行時類型從類型轉換斯卡拉

scala> val x: Any = 5 
x: Any = 5 

scala> x.asInstanceOf[Int] 
res50: Int = 5 

scala> val m1: Any = Map[String, Int]("a"->1, "b"->2) 
m1: Any = Map(a -> 1, b -> 2) 

scala> m.asInstanceOf[Map[String, Int]] 
res51: Map[String,Int] = Map(a -> 1, 2 -> b) 

scala> val m2: Any = Map[Any,Any]("a"->1, 2->"b") 
m2: Any = Map(a -> 1, 2 -> b) 

scala> m.asInstanceOf[Map[Any, Any]] 
res52: Map[Any,Any] = Map(a -> 1, 2 -> b) 

但當類型T是在運行時通過TypeTags檢索,asInstanceOf[T]不起作用。例如:

scala> val intT = typeTag[Int].tpe 
intT: reflect.runtime.universe.Type = Int 

scala> x.asInstanceOf[intT] 
<console>:12: error: not found: type intT 
       x.asInstanceOf[intT] 

錯誤說清楚,intT不是type。所以reflect.runtime.universe.Type是不是真的type?如何使用typeTag信息將值轉換爲某種類型?

回答

7

intT不是一個類型,但Type一個實例。令人困惑,當然。我不知道是否有內置的反射API,做這個東西,但你可以隨便寫,將轉換爲A給出一個元素AnyTypeTag[A]的方法。

def cast[A](a: Any, tt: TypeTag[A]): A = a.asInstanceOf[A] 

scala> val intT = typeTag[Int] 
intT: reflect.runtime.universe.TypeTag[Int] = TypeTag[Int] 

scala> val a: Any = 1 
a: Any = 1 

scala> cast(a, intT) 
res101: Int = 1 

使用隱含類的另一種變體:

implicit class TypeTagCast(a: Any) { 
    def fromTypeTag[A](tt: TypeTag[A]): A = a.asInstanceOf[A] 
} 

scala> a.fromTypeTag(intT) 
res106: Int = 1 
+0

你已經回答了我的問題,而是一個問題導致另一個,這導致了另一個。你能幫助解決這一之一:http://stackoverflow.com/questions/29400439/cast-a-variable-to-runtime-type-from-existential-typed-typecast-in-scala – Causality 2015-04-01 20:44:45

+0

這大概只能是有點用,因爲它依賴於知道「A」是用於「TypeTag」的。 – 2015-04-01 22:42:49