2014-04-06 37 views
0

请看下面的代码:斯卡拉:使用TypeTag搭配上一些的类型

def createOption[T: TypeTag](referentialData: Any) : Option[T] = { 
    Option(referentialData) match { 
    case Some(camelMessage: CamelMessage) => { 
     Option(camelMessage.body) match { 
     case Some(option: T) => Some(option) 
     case _ => None 
     } 
    } 
    case _ => None 
    } 
} 

基本上我期待返回Option(referentialData)Option[T]如果camelMessage.body非空和类型T的 的用途为有效referentialData != null 同样对于Option(camelMessage.body)

如何使用TypeTag,以确定是否camelMessage.body是类型T的

(我知道这可以被改写为不使用类型标签和选择,但我想学习如何使用类型标签,所以请不建议重新写,谢谢!)

编辑

我试着一种新的方法,因为无法找到上述解决方案,但未能获得这一个工作之一:

def createOption[T](referentialData: Any) : Option[T] = { 
    Option(referentialData) match { 
    case Some(option) => Try(option.asInstanceOf[T]).toOption 
    case _ => None 
    } 
} 

当调用这个使用createOption[Long]("test")我假设得到None回来,而是我有一个Some(String) 我在哪里错了?

+0

你的代码看起来很正确。它会做你想要的。您是否遇到特定的问题? –

+0

我跑了一个单元测试,我把T指定为Long,camelMessage.body是一个String,它返回一个Some(String)而不是None ...所以看起来不正确 – DJ180

回答

1

这是this one的副本。

但是你想ClassTag尝试它显示限制:

scala> def f[A: ClassTag](x: Any): Option[A] = x match { 
    | case y: A => println("OK"); Some(y) ; case _ => println("Nope"); None } 
f: [A](x: Any)(implicit evidence$1: scala.reflect.ClassTag[A])Option[A] 

scala> f[String]("foo") 
OK 
res0: Option[String] = Some(foo) 

scala> f[Long](2L) 
Nope 
res1: Option[Long] = None 

scala> f[java.lang.Long](new java.lang.Long(2L)) 
OK 
res2: Option[Long] = Some(2) 

scala> def f[A: TypeTag](x: Any): Option[A] = Option(x) match { 
    | case Some(y: A) => println("OK"); Some(y) ; case _ => println("Nope"); None } 
<console>:51: warning: abstract type pattern A is unchecked since it is eliminated by erasure 
     case Some(y: A) => println("OK"); Some(y) ; case _ => println("Nope"); None } 
        ^
f: [A](x: Any)(implicit evidence$1: reflect.runtime.universe.TypeTag[A])Option[A] 
+0

谢谢,虽然不是当然我明白ClassTag和TypeTag的区别。根据ScalaDoc,前者是部分描述符,而后者是完整的描述符。因此,我认为TypeTag也可以正常工作 – DJ180

+1

@ DJ180 Me ... –