【问题标题】:Why scala WrappedArray[Int](null,null) returns 0 when apply, what happened?为什么scala WrappedArray[Int](null,null)在应用时返回0,发生了什么?
【发布时间】:2018-11-22 04:39:35
【问题描述】:

在使用 sparkSql UDAF 函数时,我发现我的一些输入列意外地从 null 变为 0。

通过一些 REPL 实践,结果证明行为是 scala 2.10.5。

代码如下图

import scala.collection.mutable

val wa = mutable.WrappedArray.make[Int](Array(null, null))

wa

wa(1)

您能否请有 scala 的家人帮忙解释一下为什么以及在幕后发生了什么?

【问题讨论】:

    标签: scala apache-spark-sql user-defined-functions user-defined-aggregate


    【解决方案1】:

    你调用了方法make[Int],声明如下:

    def make[T](x: AnyRef): WrappedArray[T] = (x match {
        case null              => null
        case x: Array[AnyRef]  => new ofRef[AnyRef](x)
        case x: Array[Int]     => new ofInt(x)
        case x: Array[Double]  => new ofDouble(x)
        case x: Array[Long]    => new ofLong(x)
        case x: Array[Float]   => new ofFloat(x)
        case x: Array[Char]    => new ofChar(x)
        case x: Array[Byte]    => new ofByte(x)
        case x: Array[Short]   => new ofShort(x)
        case x: Array[Boolean] => new ofBoolean(x)
        case x: Array[Unit]    => new ofUnit(x)
      }).asInstanceOf[WrappedArray[T]]
    

    在您的情况下,xArray(null, null),它是Array[AnyRef] 的实例,因此make 创建并返回类ofRef[AnyRef] 的实例,声明为:

    final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable {
      lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass))
      def length: Int = array.length
      def apply(index: Int): T = array(index).asInstanceOf[T]
      def update(index: Int, elem: T) { array(index) = elem }
    }
    

    当你调用wa(1) 时,你调用了这个类的apply 方法,因为你的第二个元素是null,它会返回0,因为null.asInstanceOf[Int] 返回0

    【讨论】:

    • "null.asInstanceOf[Int] return 0" 是妙语(而且相当令人惊讶)
    • 非常感谢@Duelist。
    • 我刚刚发现了另一个奇怪的行为,如果我编写以下模式匹配函数,我将再次获得 null。 val f = (x:Any) => { x match { case i: Int => "integer" case null => "Null"}} f(wa(1)) f(1) f(null) 所以,它也与惰性评估有关,对吧?
    • 你能澄清一下吗?我认为您的函数没有任何问题,希望您应该添加带下划线的大小写来处理其他参数。
    • 对不起,算了。如果我只是在 scala shell 中对 val f = (x:Any) =&gt; { x match { case i: Int =&gt; "integer" case null =&gt; "Null"}} f(wa(1)) f(1) f(null) 进行评估,则不会发生 null.asInstanceOf[Int] 。结果打印为“Null”。
    猜你喜欢
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 2022-12-26
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多