我想了解为什么内联函数可以修复运行时错误。
下面的代码会导致运行时错误(参见下文)
[error] java.lang.ClassCastException: class Herbivore cannot be cast to class Food (Herbivore and Food are in unnamed module of loader sbt.internal.LayeredClassLoader @4837dd91)
trait GameObject
case class Food(x: Int) extends GameObject
case class Herbivore() extends GameObject
@main
def main: Unit =
val xs = Vector(Food(1), Herbivore(), Food(2))
def minBy[T <: GameObject](f: T => Double): Option[T] =
xs.collect{case v: T => v}.minByOption(f)
val done = minBy[Food](food => food.x)
println(done)
直到我更改它,使minBy内联并按预期工作(输出:Some(Food(1))
)。
inline def minBy[T <: GameObject](f: T => Double): Option[T] = //-snip-
这是故意的行为吗?
1条答案
按热度按时间sz81bmfz1#
键入擦除。
当JVM看到这段代码时,它只能看到
Vector[GameObject]
.泛型参数的类型测试,嗯,它不能完成,因为这个参数在运行时没有传递到方法中,所以这个检查总是成功的。由于xs的所有值都将被传递到
minByOption
中的f
中,并且您在那里不仅有Food
,因此它将需要意外的类型。在Scala 2中,您可以使用
ClassTag
添加运行时测试,但我看到您使用的是Scala 3,它具有TypeTest
,在您的情况下,它应该使用其别名Typeable
。它的行为应该像您手动编写的一样: