Warum funktioniert die Option orNull Methode haben diese überflüssig implizite argument?
-
24-10-2019 - |
Frage
Ich Frage mich, was ist der Grund für die (implicit ev: Null <:< A1)
hier:
sealed abstract class Option[+A] extends Product with Serializable {
def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null
...
}
Würde nicht
def orNull[A]: A = this getOrElse null
genug, wenn man bedenkt, dass es gar nicht zu funktionieren scheinen, mit Wert-Typen wie
Option(1).orNull
aber
Option(1).getOrElse(null)
nicht?
Option
's source code
Lösung
Nicht alle scala-Typen können null sein.Insbesondere hat zwei Kinder, AnyRef und AnyVal.AnyRef können behandeln von null-Typen.AnyVal-Typen könnten primitive auf der JVM und kann daher nicht null sein.Das implizite ist eine verzögerte Art-überprüfen, dass ermöglicht die Option[String] zu verwenden orNull aber nicht Option[Int].
Hinweis:Diese Dichotomie von Int als boxed/Objekt ohne Verpackung/primitive hat sehr seltsame Manifestationen in Scala, wie null.asInstanceOf[Int] == 0 // true.
Andere Tipps
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
^
So, null
ist für alle kein akzeptabler Typ A
, nur für die Nullable. Die Unterklassen von AnyVal
sind typische Beispiele für nicht nullbare Typen. In Abwesenheit dieses Parameters ist es nicht möglich, diese Methode zu schreiben.