消去の雨。したがって、実行時にタイプAはもう認識されず、asInstanceOf[A]
はno-opにコンパイルされます。コンパイラは結果の値がタイプAであると信じさせますが、実際には実行時には保証されません。
しかし、Scalaのマニフェストを使って回避することができます。残念なことに、JVMのプリミティブ型/ボクシングの処理では、余分な作業が必要になります。
タイプの「弱い順応」は扱えませんが、次のようなことがあります。 IntはLongと見なされないため、cast[Long](42)
はNone
を返します。それは次のようになり代わりに検証するオプションを
import scala.reflect.runtime.universe._
def as[T: TypeTag](term: Any): ValidationNEL[String, T] =
if (reflect.runtime.currentMirror.reflect(term).symbol.toType <:< typeOf[T])
term.asInstanceOf[T].successNel[String]
else
("Cast error: " + term + " to " + typeOf[T]).failNel[T]
:
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
}
整数値を文字列にキャストすると例外が発生するため、このメソッドはNoneを返しますが、そうではありません。私はscala 2.9.0-1を使用します。 –
はい、それはいくつか(2)を返しますが、そうではありません。値を 'get'しようとすると例外がスローされますが、' getOrElse'は大丈夫です。 –
まあまあ、私は例外がキャストメソッドで発生することを期待していました。 –