This thread解決了與Existential
類型一起使用時如何使用TypeTag
獲取類型參數的運行時類型。 Another thread解決了如何將變量轉換爲從TypeTag
檢索的運行時類型。從斯卡拉的存在型TypeCast向運行時類型投入變量
我的問題建立在前面提到的線程上(兩種場景的組合)。爲了清楚起見,部分代碼從兩個線程中複製而來。
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> def cast[A](a: Any, tt: TypeTag[A]): A = a.asInstanceOf[A]
cast: [A](a: Any, tt: reflect.runtime.universe.TypeTag[A])A
scala> abstract class Animal[T](implicit tt: TypeTag[T]) {
| val ttag = tt
| }
defined class Animal
scala> case object Dog extends Animal[Int]
defined object Dog
scala> case object Cat extends Animal[String]
defined object Cat
scala> val aa: List[(Animal[_], Any)] = List((Dog, 5), (Cat, "stringgg"), (Dog, 2))
aa: List[(Animal[_], Any)] = List((Dog,5), (Cat,stringgg), (Dog,2))
scala> aa(0)._1.ttag
res25: reflect.runtime.universe.TypeTag[_] = TypeTag[Int]
scala> aa(1)._1.ttag
res26: reflect.runtime.universe.TypeTag[_] = TypeTag[String]
scala> cast(aa(0)._2, aa(0)._1.ttag)
res27: Any = 5
scala> cast(aa(1)._2, aa(1)._1.ttag)
res28: Any = stringgg
總之,最後兩行:cast(value, TypeTag[_])
總是返回Any
類型的值。但我的意圖是將這些值轉換爲存儲在Dog|Cat.ttag
中的正確類型,但不幸的是,由於使用了類型,因此不是TypeTag[Int]
或TypeTag[String]
,而是TypeTag[_]
。有沒有解決方案?
編輯1:
儘管字段ttag
是TypeTag[_]
類型的,ttag.tpe
確實有正確的 「類型」(但作爲reflect.runtime.universe.Type
一個實例)。是否有可能使用typetag.tpe
投射到正確的類型?
這是一段時間,因爲我所訪問過這個帖子,但我已經有了一些新的想法返回。我不認爲'cast'方法可以像你想要的那樣工作,因爲'TypeTag'只在運行時纔有用,並且在編譯時執行。編譯器需要知道'cast'的返回類型是什麼,但它不能從'TypeTag [_]'中推斷出正確的'A'。根據你想要對結果做什麼,可能會使它以不同的方式工作。 – 2015-05-15 14:37:10
不僅''cast'處於編譯時,'TypeTag'處於運行時,而且由於'存在類型'具有集合,'TypeTag'在'Any'上,而不是它的真實類型。我一直使用的替代方法是使用超類來指示類型,例如'List((Dog,5,IntType),(Cat,「stringgg」,StrType),(Dog,2,IntType))'',然後通過'asInstanceOf'執行一次「運行時」。這個「運行時間」轉換在我的練習中非常有用,但它並不安全,我希望有一種編譯器時間轉換的機制。 – Causality 2015-05-18 23:10:14