Das bedeutet, dass Option [Nothing] ist ein Subtyp von Option [Int] (wegen der Kovarianz), richtig?
Richtig. Option[Nothing]
ist ein Option[Int]
.
Aber mit B>: A haben wir gesagt, dass B ein Supertyp sein muss ?! Wie können wir einen Int zurück bekommen?
Es muss kein Supertyp sein. Es erfordert nur A
als unteren gebundenen. Das bedeutet, dass Sie Int
weiterhin an getOrElse
übergeben können, wenn A
Int
ist.
Aber das bedeutet nicht, dass Sie Instanzen einer Unterklasse nicht übergeben können. Zum Beispiel:
class A
class B extends A
class C extends B
scala> Option(new B)
res196: Option[B] = Some([email protected])
scala> res196.getOrElse(new C)
res197: B = [email protected]
scala> res196.getOrElse(new A)
res198: A = [email protected]
scala> res196.getOrElse("...")
res199: Object = [email protected]
Ich kann immer noch eine Instanz von C
, übergeben, da C
up-Cast zu B
sein kann. Ich kann auch einen Typ höher in der Vererbungsstruktur übergeben, und getOrElse
wird stattdessen diesen Typ zurückgeben. Wenn ich einen Typ übergebe, der nichts mit dem Typ zu tun hat, der in der Option
enthalten ist, dann wird der Typ mit der geringsten Obergrenze abgeleitet. Im obigen Fall ist es Any
.
Also warum ist die Untergrenze dort überhaupt? Warum nicht haben:
def getOrElse[B <: A](default: => B): B
Das wird nicht funktionieren, weil getOrElse
entweder müssen die A
zurück, die B
im Option
, oder die Standard enthalten ist. Aber wenn wir die A
zurückgeben, und A
ist kein B
, so ist der typgebundene ungültig.Vielleicht, wenn getOrElse
zurück A
:
def getOrElse[B <: A](default: => B): A
Dies funktionieren würde (wenn es wirklich so definiert wurde), aber Sie würden durch die Art-Grenzen überschritten werden. In meinem obigen Beispiel konnten Sie also nur B
oder C
an getOrElse
über eine Option[B]
übergeben. Auf jeden Fall ist dies nicht in der Standardbibliothek.
Die Standardbibliothek getOrElse
ermöglicht es Ihnen, alles zu übergeben. Angenommen, Sie haben Option[A]
. Wenn wir einen Untertyp von A
übergeben, wird er auf A
hochgerechnet. Wenn wir A
passieren, ist das offensichtlich in Ordnung. Und wenn wir einen anderen Typ übergeben, dann leitet der Compiler die kleinste obere Grenze zwischen den beiden ab. In allen Fällen ist die typgebundene B >: A
erfüllt.
Da getOrElse
Ihnen erlaubt, alles zu übergeben, halten viele es für sehr schwierig. Zum Beispiel könnten Sie haben:
val number = "blah"
// ... lots of code
val result = Option(1).getOrElse(number)
Und das wird kompilieren. Wir haben nur eine Option[Any]
, die wahrscheinlich irgendwo anderswo einen Fehler verursacht.
Vielen Dank, aber könnten Sie bitte ein Beispiel dafür geben, welchen Typ wir nicht an res196.getOrElse übergeben können ... Derzeit sehe ich in diesem Beispiel keine untere Grenze. Oder besser zu sagen, ich verstehe jetzt nicht, was es für einen Typ bedeutet, eine untere Grenze zu sein ... – Marin
@Marin Sie können jeden beliebigen Typ an 'getOrElse' übergeben. Siehe meine Bearbeitung. –
danke! Ich denke, ich verstehe es jetzt. – Marin