2015-12-29 53 views
0

考虑:使用类型标签,以检查的预期类型相匹配实际

sealed trait Parent 
case class Boy(info: String) extends Parent 
case class Girl(info: String) extends Parent 

于是,我写了下面f功能。给定一个result和期望的结果类型,它打印出的支票是否成功:

import scala.reflect.runtime.universe._ 

scala> def f[A:TypeTag, B:TypeTag](result: A): Unit = typeOf[A] match { 
    | case t if t =:= typeOf[B] => println("good") 
    | case _     => println("bad") 
    | } 
f: [A, B](result: A)(implicit evidence$1: reflect.runtime.universe.TypeTag[A], implicit evidence$2: reflect.runtime.universe.TypeTag[B])Unit 

然后,我跑了它:

scala> f[Boy, Girl](Boy("foo")) 
bad 

scala> f[Boy, Boy](Boy("foo")) 
good 

对于我的测试目的(无视println语句的使用以表示成功),我的使用是否正确?另外,在f中是否存在运行时异常的风险?如果是这样,怎么样?

回答

4

是我使用TypeTag的正确吗?

TypeTag如果您手动提供类型参数,则不是真的需要。这大致相当于:

def f[A](result: A): Unit = ??? 

f[Girl](boy)甚至不会编译如果boyBoy,所以失败的情况下是没有用的。

对于def f[A: TypeTag, B: TypeTag](result: A): Unit,不需要的result的实际情况,因为你手动比较TypeTag S的AB,您手动指定类型的参数。这相当于在没有实例的情况下说typeOf[A] =:= typeOf[B]

另外,在f中是否存在运行时异常的风险?

不是。你不得不做一些真正邪恶的,喜欢做自己TypeTag S:

scala> implicit val tt: TypeTag[Boy] = null.asInstanceOf[TypeTag[Boy]] 
tt: reflect.runtime.universe.TypeTag[Boy] = null 

scala> f[Boy, Girl](Boy("foo")) 
java.lang.NullPointerException 

只要你使用编译器生成的TypeTag,应该没事。

+0

'不需要结果的实际情况,因为你手动comparing'在这种情况下的话,我想简单地调用'type'方法?例子:'case class F(x:Int)| val y = F(5)| TYPEOF [y.type]'? –

+0

如果你想要一个实例的类型,你需要一个'TypeTag',但问题是你需要两个类型参数:一个是你想推断的,另一个是你提供的,但是Scala没有办法提供一个并推断另一个。 –

+0

@ m-z其实,有一种方法可以实现这个结果。 (另外,我会澄清,你的第一句话适用于这个特定的情况,而不是一般情况。) –

0

这里是你如何提供一个参数,并推断出其他:

case class F[B: TypeTag] { 
    def apply[A: TypeTag](x: A) = println(typeOf[A] =:= typeOf[B]) 
} 

F[Girl].apply(Boy("Foo")) // Boy inferred for A 
相关问题