Неявные преобразования в row.getAs [Long] - PullRequest
2 голосов
/ 18 февраля 2020

Когда я пытаюсь применить функцию фильтрации к кадру данных, я сталкиваюсь с запутанной проблемой.

Если поля строки равны 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
      })

Результат отладки идеи: enter image description here

Я могу понять, isNotNull2 верно, как do c из getAs[T](fieldName: String) говорит For primitive types if value is null it returns 'zero value' specific for primitive.

Были ли здесь scala неявные преобразования? Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2020

Основная проблема заключается в том, что дженерики на самом деле не работают с примитивными типами. 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, что верно.

0 голосов
/ 18 февраля 2020

Компилятор Scala часто может определить тип выражения, поэтому нам не нужно объявлять его явно.

При оценке val isNotNull1 = (row.getAsLong! = Null) row.getAsLong имеет значение null , а null! = Null равно false. При оценке val videoId = row.getAsLong row.getAsLong по-прежнему будет иметь значение null , однако компилятор определит, что это Long, и NULL будет присвоено 0, поскольку примитив не может быть нулевым.

Кроме того, в приведенном ниже коде 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...