我将继续翻译关于奇怪源代码的系列文章。这是这个系列的一篇。
看着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
B
是一个原始类型,那么var acc: B = null
将无法工作。 - Dima