简体   繁体   中英

In Scala, how to cast a value when a TypeTag is available

Given

  • a value of type Any
  • a TypeTag corresponding to the desired type

How can I cast the value

Unfortunately, the following snippet doesn't compile

val v: Any = 123
val tag    = typeTag[Int]
val i      = v.asInstanceOf[t.tpe]

Use this

import scala.reflect.ClassTag

def getTypedArg[T: ClassTag](any: Any): Option[T] = {
      any match {
        case t: T => Some(t)
        case invalid =>
          None
      }
}

Usage

scala> getTypedArg[Int](5)
res1: Option[Int] = Some(5)

scala> getTypedArg[Int]("str")
res2: Option[Int] = None

Source: Retrieve class-name from ClassTag


EDIT-1

As asked by @Aki , it can be made to work with TypeTag s too, with this hack

import reflect.runtime.universe._
import scala.reflect.ClassTag

def typeToClassTag[T: TypeTag]: ClassTag[T] = {
  ClassTag[T]( typeTag[T].mirror.runtimeClass( typeTag[T].tpe ) )
}

def getTypedArg2[T: TypeTag](any: Any): Option[T] = {
  implicit val c: ClassTag[T] = typeToClassTag[T]
  any match {
    case t: T => Some(t)
    case invalid =>
      None
  }
}

Reference: How to get ClassTag form TypeTag, or both at same time?

You could write your own method that does the casting.
(note that this method will never throw ClassCastExceptions)

def cast[A](a: Any, tag: TypeTag[A]): A = a.asInstanceOf[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