Mi viene in mente un uso, ed è qualcosa che è stato considerato come un miglioramento del linguaggio di programmazione Swift.
Swift ha una maybe
Monade, scritta Optional<T>
o T?
. Esistono molti modi per interagire con esso.
È possibile utilizzare come da scartare condizionato come
if let nonOptional = someOptional {
print(nonOptional)
}
else {
print("someOptional was nil")
}
È possibile utilizzare map
, flatMap
per trasformare i valori
- L'operatore di riavvolgimento forzato (
!
, di tipo (T?) -> T
) per scartare forzatamente il contenuto, altrimenti provoca un arresto anomalo
L'operatore a coalescenza zero ( ??
, di tipo (T?, T) -> T
) per assumere il suo valore o utilizzare in altro modo un valore predefinito:
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
Sfortunatamente, non c'era un modo conciso di dire "scartare o lanciare un errore" o "scartare o andare in crash con un messaggio di errore personalizzato". Qualcosa di simile a
let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")
non viene compilato perché fatalError
ha tipo () -> Never
( ()
è Void
, tipo di unità Never
Swift , è il tipo in basso di Swift). Chiamandolo produce Never
, che non è compatibile con l' T
atteso come operando di destra ??
.
Nel tentativo di porre rimedio a questo, Swift Evolution propsoal SE-0217
- L'operatore " Unwrap or Die" è stato lanciato. Alla fine è stato respinto , ma ha suscitato interesse nel diventare Never
un sottotipo di tutti i tipi.
Se è Never
stato creato per essere un sottotipo di tutti i tipi, l'esempio precedente sarà compilabile:
let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")
perché il sito di chiamata di ??
ha tipo (T?, Never) -> T
, che sarebbe compatibile con la (T?, T) -> T
firma di ??
.
(x ? 3 : throw new Exception())
viene sostituito a scopo di analisi con qualcosa di più simile(x ? 3 : absurd(throw new Exception()))
?