【问题标题】:Implicit conversions in row.getAs[Long]row.getAs[Long] 中的隐式转换
【发布时间】:2020-06-02 14:41:06
【问题描述】:

当我尝试在数据框上应用过滤器功能时,我遇到了一个困惑的问题。

如果一行的字段为null,则isNotNull1 为假,isNotNull2 为真。代码如下:

      val res = df.filter(row => {
        val isNotNull1 = (row.getAs[Long]("video_id") != null)
        val videoId = row.getAs[Long]("video_id")
        val isNotNull2 = (videoId != null)
        isNotNull2
      })

想法调试结果:

我可以理解isNotNull2 是真的,正如getAs[T](fieldName: String) 的文档所说For primitive types if value is null it returns 'zero value' specific for primitive

这里是否发生了 scala 隐式转换?谢谢你的帮助。

【问题讨论】:

    标签: scala dataframe apache-spark


    【解决方案1】:

    Scala 编译器通常可以推断出表达式的类型,因此我们不必显式声明它。

    评估 val isNotNull1 = (row.getAsLong != null) row.getAsLong 为 null 并且 null != null 为 false。 在评估 val videoId = row.getAsLong row.getAsLong 仍将为 null 但编译器推断它是 Long 并且 null 将分配给 0,因为原语不能为 null。

    此外,在下面的代码中,videoId_wrong 将引发编译器错误,它是一个 Long 并且已被明确推断为 String。

    val res = df.filter(row => {
      val isNotNull1 = (row.getAs[Long]("video_id") != null)
      val videoId_wrong: String = row.getAs[Long]("video_id")
      val videoId = row.getAs[Long]("video_id")
      val isNotNull2 = (videoId != null)
      isNotNull2
    })
    

    https://docs.scala-lang.org/tour/type-inference.html

    【讨论】:

      【解决方案2】:

      根本问题是泛型真正不能与原始类型一起使用。 Scala 编译器试图呈现他们所做的错觉,但您偶然发现了它失败的情况。

      所以row.getAs[Long]("video_id") 是“真的”row.getAs[java.lang.Long]("video_id") 在你的情况下返回null,所以val isNotNull1 行比较null != null 这是错误的。

      val videoId这一行,因为它的类型是Long,所以变成row.getAs[java.lang.Long]("video_id").asInstanceOf[Long]。这是0,在下一行你是0.asInstanceOf[java.lang.Long] != null,这是真的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-01
        • 1970-01-01
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多