Continuing my series about strange source code.
Looking at Scala 2.12.12 scala.collection.TraversableOnce#reduceLeft#reducer
I've found a very strange line:
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
}
What actually 0.asInstanceOf[B]
does? Is it a workaround for making each type "nullable"?
For example, having
Seq("1", "2").reduceLeft(_ + _)
means the following code in the runtime
var acc: B = 0.asInstanceOf[String]
Why this cannot be simply replaced with var acc: B = null
? Because it would require to introduce implicit ev: Null <:< A1
or what?
Update:
Moreover, simply casting Int
to any other type throws an exception:
println(0.asInstanceOf[String])
Throws a runtime exception:
Exception in thread "main" java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String
But why it doesn't throw an exception in case with reducer?
Update 2:
Diving deeper,
def foo[A]: A = 1.asInstanceOf[A]
println(foo[String]) // 1
println(foo[LocalDateTime]) // 1
println(foo[LocalDateTime].getClass) // java.lang.Integer