Ich kann mir eine Verwendung vorstellen, die als Verbesserung der Swift-Programmiersprache angesehen wurde.
Swift hat eine maybe
Monade, Dinkel Optional<T>
oder T?
. Es gibt viele Möglichkeiten, damit zu interagieren.
Sie können das bedingte Auspacken wie verwenden
if let nonOptional = someOptional {
print(nonOptional)
}
else {
print("someOptional was nil")
}
Sie können verwendet werden map
, um flatMap
die Werte zu transformieren
- Der Operator "Force Unwrap" (
!
vom Typ " Force Unwrap" (T?) -> T
), um das gewaltsame Auspacken des Inhalts zu erzwingen, andernfalls wird ein Absturz ausgelöst
Der Null-Koaleszenz-Operator ( ??
vom Typ (T?, T) -> T
), um seinen Wert zu übernehmen oder auf andere Weise einen Standardwert zu verwenden:
let someI = Optional(100)
print(someI ?? 123) => 100 // "left operand is non-nil, unwrap it.
let noneI: Int? = nil
print(noneI ?? 123) // => 123 // left operand is nil, take right operand, acts like a "default" value
Leider gab es keine prägnante Möglichkeit zu sagen: "Fehler auspacken oder auslösen" oder "Mit einer benutzerdefinierten Fehlermeldung auspacken oder abstürzen". Etwas wie
let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")
Kompiliert nicht, weil fatalError
es den Typ hat () -> Never
( ()
ist Void
der Einheitentyp von Never
Swift, der unterste Typ von Swift). Der Aufruf erzeugt Never
, was nicht mit dem T
erwarteten richtigen Operanden von kompatibel ist ??
.
Um dem abzuhelfen, wurde der Vorschlag von Swift Evolution SE-0217
- The Unwrap or Die veröffentlicht . Es wurde letztendlich abgelehnt , aber es weckte das Interesse, Never
einen Untertyp aller Art zu machen.
Wenn Never
als Subtyp aller Typen festgelegt wurde, kann das vorherige Beispiel kompiliert werden:
let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")
weil die aufrufstelle von ??
typ hat (T?, Never) -> T
, der mit der (T?, T) -> T
signatur von kompatibel wäre ??
.
(x ? 3 : throw new Exception())
für Analysezwecke durch so etwas wie ersetzt wird(x ? 3 : absurd(throw new Exception()))
?