0
我想以一個字符串的形式獲取類型的名稱,沒有運行時反射。Scala:獲取沒有運行時反射並且沒有類型實例的類型名稱
使用宏,並與類型的實例,我能做到這樣的:
def typeNameFromInstance[A](instance: A): String =
macro typeNameFromInstanceImplementation[A]
def typeNameFromInstanceImplementation[A](
c: Context)(
instance: c.Expr[A]): c.Expr[String] = {
import c.universe._
val name = instance.actualType.toString
c.Expr[String](Literal(Constant(name)))
}
我怎麼能做到這一點,而不類型的實例?我想一個函數簽名,如:
def typeName[A]: String
我不能使用ClassTags,因爲它們不提供完整的類型名稱,只是擦除類型。由於thread safety issues,我顯然也不能使用TypeTags。
編輯:這似乎是不可能的完全一般性(例如嵌套函數調用)。下面接受的答案在評論中說明了這一點。
該解決方案不會返回最終的靜態類型。假設我定義了:「def printType [A] = println(typeName [A])」。然後調用「printType [List [Int]]」打印「A」而不是「List [Int]」。 – emchristiansen 2013-03-27 18:23:15
如果你希望它能像這樣工作,那麼我認爲沒有'TypeTag's是不可能的。宏在編譯過程中被擴展,所以你的代碼:def printType [A] = println(typeName [A])'實際上被轉換爲'def printType [A] = println(「A」)''。你唯一能做的就是將'printType'定義爲一個宏。它的實現可能如下所示:'def printType_impl [T](c:Context):c.Expr [Unit] = c.universe.reify(println(typeName_impl [T](c).splice))' – ghik 2013-03-27 18:59:53