scala – 一些带有asInstanceOf的构造函数

当我写
recent answer时,我也尝试以更“功能”的方式解决问题,但遇到以下问题:

scala> "1".asInstanceOf[Int]
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source)
        ...

scala> Some("1".asInstanceOf[Int])
res29: Some[Int] = Some(1)

而且只有

scala> res29.get
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source)
        ...

看起来Some的参数是惰性求值的,但我在the sources中找不到任何线索.As构造函数中的x参数是严格的.

为什么有些asInstanceOf会有这么奇怪的行为?

最佳答案 构造函数参数未被延迟评估.您收到错误的那一刻是REPL尝试显示结果的时刻,作为Int(unboxToInt).如果你进一步查看堆栈,你会发现scala_repl_result.

我相信问题是asInstanceOf [Int]在运行时根本没有检查.我不知道它是否符合规范(对于值类型)或bug.编译器被欺骗接受“1”是Int(或盒装Int),等待asInstanceOf暗示的运行时检查,但不会发生.

由于Option / Some不是专用的,因此在运行时只有Some [Object].因此,对于JVM,调用构造函数new Some(Object o),它在代码验证和运行时被接受. toString(由新建的Some上的REPL调用)在通用代码中,其中T也被视为Object(或AnyRef),因此它可以工作,并显示Some(1).另一方面,每次在编译器知道泛型参数类型的上下文中访问值时,都会在代码中插入强制转换(在值类型的情况下取消装箱).这是它实际失败的时候(这里REPL在显示之前进行拆箱).

编辑这是在Scala 2.8.1中.根据@incrop上面的评论,现在已经修复了.

点赞