Давайте скажем, что у меня есть такой массив:
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
*** Если вас интересует контекст, вы можете взглянуть на Использование содержит в Scala - исключение
**** Другие актуальные вопросы, связанные с комментариями: