Perché il metodo orNull dell'opzione hanno questo argomento implicito superfluo?
-
24-10-2019 - |
Domanda
Mi chiedo qual è la ragione per la (implicit ev: Null <:< A1)
qui:
sealed abstract class Option[+A] extends Product with Serializable {
def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null
...
}
Non sarebbe
def orNull[A]: A = this getOrElse null
essere abbastanza considerando che non sembra nemmeno di lavorare con tipi di valore come
Option(1).orNull
ma
Option(1).getOrElse(null)
fa?
Soluzione
Non tutti i tipi di Scala possono essere nulli. In particolare, qualsiasi ha due figli, AnyRef e AnyVal. AnyRef può gestire tipi nulli. tipi AnyVal potrebbero essere primitivi sulla JVM e quindi non possono essere nulli. L'implicita è un tipo di controllo che permette ritardato Opzione [String] per utilizzare orNull ma non Opzione [Int].
Nota: Questa dicotomia di Int essere inscatolato / oggetto unboxed / primitiva ha molto strane manifestazioni in Scala, come null.asInstanceOf [Int] == ??0 // true
.Altri suggerimenti
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
^
Quindi, null
non è un tipo accettabile per tutti A
, solo per i più nullable. Le sottoclassi di AnyVal
sono tipici esempi di tipi non annullabili. In assenza di tale parametro, non è possibile scrivere questo metodo.