Erasure deszcze na swojej parady tutaj. Dlatego w czasie wykonywania typ A nie jest już znany, a asInstanceOf[A]
jest kompilowany do trybu bez operacji. Po prostu sprawia, że kompilator uważa, że wynikowa wartość jest typu A, ale w rzeczywistości nie jest to zapewnione w środowisku wykonawczym.
Możesz używać manifestów Scali do obejścia tego. Niestety postępowanie JVM z prymitywnymi typami/boksami zmusza nas do wykonania dodatkowej pracy.
Następujące prace, mimo że nie obsługują "słabej zgodności" typów, co oznacza np. Int nie jest uważany za długi, więc cast[Long](42)
zwracazwraca.
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
}
Przesyłanie wartości całkowitych do łańcucha znaków powinno prowadzić do wyjątku, a metoda powinna zwrócić wartość None, ale tak nie jest. Używam scala 2.9.0-1 –
Tak, zwraca Some (2), ale ... nie. Próba 'get' wartości powoduje wyjątek, ale' getOrElse' jest w porządku. –
Tak, oczekiwałem, że wyjątek stanie się w metodzie rzutowania. –