泛型函数中类型转换的 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
,就会触发异常。
谁能解释为什么会这样?
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 aClassCastException
at runtime, while the expressionList(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
,就会触发异常。