简体   繁体   中英

Scala: Using a TypeTag to match on a Some's type

See the following code:

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
  }
}

Basically I am looking to return an Option[T] if camelMessage.body is non-null and of type T. The uses of Option(referentialData) is effectively referentialData != null Likewise for Option(camelMessage.body)

How do I use the TypeTag to determine if camelMessage.body is of type T.

(I know this can be re-written to not use TypeTags and Options but I want to learn how to use TypeTags so please no suggestions to re-write, thanks!)

Edit

I tried a new approach as could not find a solution for the above, but could not get this one to work either:

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

When I invoke this using createOption[Long]("test") I was presuming to get a None back, but instead I got a Some(String) Where am I going wrong here?

This is a duplicate of this one .

But you want to try it with ClassTag to show the limitation:

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]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM