Почему метод orNull Option имеет этот лишний неявный аргумент?
-
24-10-2019 - |
Вопрос
Интересно, в чем причина (implicit ev: Null <:< A1)
здесь:
sealed abstract class Option[+A] extends Product with Serializable {
def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null
...
}
Не стал бы
def orNull[A]: A = this getOrElse null
этого будет достаточно, учитывая, что он, похоже, даже не работает с такими типами значений, как
Option(1).orNull
но
Option(1).getOrElse(null)
делает?
Option
's исходный код
Решение
Не все типы Scala могут быть нулевыми.В частности, у Any есть два дочерних элемента: AnyRef и AnyVal.AnyRef может обрабатывать нулевые типы.Типы AnyVal могут быть примитивами в JVM и, следовательно, не могут иметь значение NULL.Неявным является отложенная проверка типа, которая позволяет Option[String] использовать orNull, но не Option[Int].
Примечание:Эта дихотомия Int как упакованного/распакованного объекта/примитива имеет очень странные проявления в Scala, например, null.asInstanceOf[Int] == 0 // true.
Другие советы
scala> abstract class Op[A] {
| def getOrElse(b: A): A
| def orNull[A]: A = this getOrElse null
| }
<console>:14: error: type mismatch;
found : Null(null)
required: A
def orNull[A]: A = this getOrElse null
^
Так, null
не является приемлемым типом для всех A
, только для нулевых. Подклассы AnyVal
являются типичными примерами не нулевых типов. В отсутствие этого параметра невозможно написать этот метод.