奇怪的Scala ClassCastException

时间:2018-04-19 20:30:45

标签: scala exception casting

以下代码编译,但在最后一行引发异常。为什么是这样?我怎么能避免呢? (下面的代码是为了显示问题而设计的;我确实需要在实际代码中做类似的事情。)

type F = Int => Int

val f: Int => Int = identity
val g1: F => F = identity
val g2: F => F = (identity _).asInstanceOf[F => F]

println("f = " + f)
println("g1 = " + g1)
println("g2 = " + g2)

val h1: Int => Int = g1(f: Int => Int)
val h2: Int => Int = g2(f: Int => Int)

以下是代码的输出:

f = doodle.Bug$$$Lambda$7/1836797772@4b53f538
g1 = doodle.Bug$$$Lambda$8/1383547042@543e710e
g2 = doodle.Bug$$$Lambda$9/3213500@57f23557

以下是例外:

java.lang.ClassCastException: doodle.Bug$$$Lambda$7/1836797772 cannot be cast to scala.runtime.Nothing$

我发现施放g2会导致对f进行隐式转换,这一点特别奇怪......

1 个答案:

答案 0 :(得分:2)

狂野猜测:菊石表示:

(identity _)

的类型为:

Nothing => Nothing
Scala可能记得这个事实。也许是因为专业化或(更有可能)可能Eta扩展identity创建了一个闭包,记住它是Nothing => Nothing函数,位于调用identity下面。

在这种情况下,当你在JVM进行实际检查的上下文中使用它时(所以不是在你运行asInstanceOf时,而是在应用程序期间),然后转换失败,你会看到异常。

identity[F] _

毫无例外地按预期工作。