次のような配列があるとしましょう*:
val foo: Any = 1 : Int
Option(foo.asInstanceOf[String])
明らかな理由で失敗します:
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
次に、次のクラスを考えてみましょう。
case class DummyRow() {
val foo: Any = 1 : Int
def getAs[T] = foo.asInstanceOf[T]
def getAsOption[T] = Option(foo.asInstanceOf[T])
}
私が知る限りgetAs
、前の のapply
後にasInstanceOf
.
驚くべきことに、そうではありません。単独で呼び出すと、例外がスローされます。
DummyRow().getAs[String]
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
しかし、ラップされた場合はOption
成功します:
val stringOption = Option(DummyRow().getAs[String])
// Option[String] = Some(1)
DummyRow().getAsOption[String]
// Option[String] = Some(1)
ラップされた値にアクセスしようとした場合にのみ失敗します:
stringOption.get
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
それで、ここで何が起こりますか?制限されているように見えるClassCastException
ので、型消去のような醜いものに関連していると思います。
*サード パーティのコードの動作を模倣するためAny
にasInstanceOf
存在するので、それについて詳しく説明しないでください。
** Scala 2.10.5、2.11.7 でテスト済み
*** コンテキストに興味がある場合は、Using contains in scala - exception を参照してください。
**** コメントにリンクされているその他の関連する質問: