以下代码编译,但在最后一行引发异常。为什么是这样?我怎么能避免呢? (下面的代码是为了显示问题而设计的;我确实需要在实际代码中做类似的事情。)
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
进行隐式转换,这一点特别奇怪......
答案 0 :(得分:2)
狂野猜测:菊石表示:
(identity _)
的类型为:
Nothing => Nothing
Scala可能记得这个事实。也许是因为专业化或(更有可能)可能Eta扩展identity
创建了一个闭包,记住它是Nothing => Nothing
函数,位于调用identity
下面。
在这种情况下,当你在JVM进行实际检查的上下文中使用它时(所以不是在你运行asInstanceOf
时,而是在应用程序期间),然后转换失败,你会看到异常。
identity[F] _
毫无例外地按预期工作。