泛型函数中类型转换的 Scala 怪异行为

Scala weird behavior for type conversion in generic function

谁能解释为什么会这样?

scala> def as[T](v: Any) = Try(v.asInstanceOf[T])
as: [T](v: Any)scala.util.Try[T]

scala> as[Int]("Hello")
res0: scala.util.Try[Int] = Success(Hello)

scala> res0.map(_ + 1)
res1: scala.util.Try[Int] = Failure(java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer)

这与装箱无关,因为您可以使用自己的类型而不是 Int,并且它的行为方式相同。

似乎也不是关于名字参数,因为你可以用 Option 替换 Try 并且它是一样的。

我猜是关于擦除,但也许有人可以给出详细的解释?

都在scaladoc:

Note that the success of a cast at runtime is modulo Scala's erasure semantics. Therefore the expression 1.asInstanceOf[String] will throw a ClassCastException at runtime, while the expression List(1).asInstanceOf[List[String]] will not. In the latter example, because the type argument is erased as part of compilation it is not possible to check whether the contents of the list are of the requested type.

所以,因为 T 被擦除,Try(v.asInstanceOf[T]) 不会立即抛出一个 ClassCastException,因为就 JVM 所知,你有一个 Try[Any]。但是,一旦您尝试将包含的类型视为 Int,就会触发异常。