【发布时间】:2021-07-03 10:50:55
【问题描述】:
继续my series关于奇怪的源代码。
查看 Scala 2.12.12 scala.collection.TraversableOnce#reduceLeft#reducer 我发现了很奇怪的一行:
def reduceLeft[B >: A](op: (B, A) => B): B = {
if (isEmpty)
throw new UnsupportedOperationException("empty.reduceLeft")
object reducer extends Function1[A, Unit] {
var first = true
var acc: B = 0.asInstanceOf[B] // <<<<===
override def apply(x: A): Unit =
if (first) {
acc = x
first = false
}
else acc = op(acc, x)
}
self foreach reducer
reducer.acc
}
0.asInstanceOf[B] 实际上是做什么的?这是使每种类型“可空”的解决方法吗?
例如,拥有
Seq("1", "2").reduceLeft(_ + _)
表示运行时中的以下代码
var acc: B = 0.asInstanceOf[String]
为什么不能简单地用var acc: B = null 代替?因为它需要介绍implicit ev: Null <:< A1或什么?
更新:
此外,简单地将Int 转换为任何其他类型都会引发异常:
println(0.asInstanceOf[String])
抛出运行时异常:
Exception in thread "main" java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String
但是为什么在使用reducer的情况下它不会抛出异常?
更新 2:
潜水更深,
def foo[A]: A = 1.asInstanceOf[A]
println(foo[String]) // 1
println(foo[LocalDateTime]) // 1
println(foo[LocalDateTime].getClass) // java.lang.Integer
【问题讨论】:
-
是的,这似乎是一种欺骗编译器使其具有空值的方法。
-
@LuisMiguelMejíaSuárez 是的。但是行为是如此奇怪......我在问题中添加了几个例子来证明它的行为有多荒谬:D
-
坏演员有点像一棵树,倒在森林里:只有当你看它时它才会抛出。
-
如果
B是原语,var acc: B = null将不起作用。
标签: scala null scala-collections