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