Erasure идет дождь на вашем параде здесь. Поэтому во время выполнения тип A больше не известен, и asInstanceOf[A]
компилируется в no-op. Это просто заставляет компилятор поверить, что результирующее значение имеет тип A, но на самом деле это не гарантируется во время выполнения.
Вы можете использовать манифесты Скалы, чтобы обойти это, однако. К сожалению, обработка JVM примитивных типов / бокса вынуждает нас сделать некоторую дополнительную работу.
Следующее работает, хотя оно не обрабатывает "слабое соответствие" типов, то есть, например, Int не считается длинным, поэтому cast[Long](42)
возвращает None
.
def cast[A : Manifest](value: Any): Option[A] = {
val erasure = manifest[A] match {
case Manifest.Byte => classOf[java.lang.Byte]
case Manifest.Short => classOf[java.lang.Short]
case Manifest.Char => classOf[java.lang.Character]
case Manifest.Long => classOf[java.lang.Long]
case Manifest.Float => classOf[java.lang.Float]
case Manifest.Double => classOf[java.lang.Double]
case Manifest.Boolean => classOf[java.lang.Boolean]
case Manifest.Int => classOf[java.lang.Integer]
case m => m.erasure
}
if(erasure.isInstance(value)) Some(value.asInstanceOf[A]) else None
}