2017-04-10 111 views
1

我想提出一個案例類Bla,它採用類型參數A,它在運行時知道A的類型(它將其存儲在其info字段中)。TypeTag用於案例分類

我的嘗試如下例所示。問題是這個例子不能編譯。

case class Bla[A](){ 
    val info=Run.paramInfo(this) // this does not compile 
} 
import scala.reflect.runtime.universe._ 

object Run extends App{ 
    val x=Bla[Int] 
    def paramInfo[T](x:T)(implicit tag: TypeTag[T]): String = { 
    val targs = tag.tpe match { case TypeRef(_, _, args) => args } 
    val tinfo=s"type of $x has type arguments $targs" 
    println(tinfo) 
    tinfo 
    } 
    paramInfo(x) 
} 

然而,當我評論val info=Run.paramInfo(this)然後該程序運行正常,並打印:

型血乳酸(的)有類型參數列表(INT)

有沒有一種方法,使這個例子下面編譯? (或以某種其他方式實現相同的目標,即案例類是自我意識到它的類型參數的類型?)

回答

2

您只需要將隱式類型標記參數傳遞給案例類構造函數(否則類型信息調用paraInfo需要的話)之前丟失:

case class Bla[A : TypeTag]() { ... } 

這是簡寫:

case class Bla[A](implicit tag: TypeTag[A]) { ... } 
+0

謝謝,這工作。 – jhegedus

3

有沒有在使用基於反射的API爲這個小點,無形具有暴露組合物1一個類型類使用隱式宏將時間信息發送到運行時。

import shapeless.Typeable 


class Test[T : Typeable] { 
    def info: String = implicitly[Typeable[T]].describe 
} 

它也比較容易在這裏推出自己的事,與具有編譯隱含宏在不同的編譯單元比無論是使用它的加入不便。

+0

謝謝,不是在使用TypeTag時編譯時確定的'info'的值? – jhegedus

+1

@jhegedus Nope,'TypeTag'是一個反射API的東西,它是java的'Class [_]'的更進化版本。 – flavian

+0

TypeTag的值似乎是在編譯時決定的:「就像scala.reflect.Manifest一樣,TypeTag可以被認爲是在編譯時可以運行的所有類型信息的對象,例如TypeTag [T ]封裝了一些編譯時類型T的運行時類型表示。但是請注意,TypeTags應該被認爲是對2.10之前的Manifest概念的更豐富的替代,它們還與Scala反射完全集成。「 http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html – jhegedus