2016-05-20 17 views
11

Come funziona la covarianza per Optional s in Swift?Come funziona la covarianza facoltativa in Swift

Dire scrivo il seguente codice:

var nativeOptionalView: Optional<UIView> 
let button = UIButton() 
nativeOptionalView = .Some(button) 
var nativeOptionalButton = Optional.Some(button) 

nativeOptionalView = nativeOptionalButton 

Si compila e funziona bene. Tuttavia, se mi definisco MyOptional come

enum MyOptional<T> { 
    case Some(T) 
    case None 
} 

e scrivere la seguente:

var myOptionalView: MyOptional<UIView> 
let button = UIButton() 
myOptionalView = .Some(button) 
var myOptionalButton = MyOptional.Some(button) 

myOptionalView = myOptionalButton 

ottengo l'errore:

error: cannot assign value of type ' MyOptional<UIButton> ' to type ' MyOptional<UIView> '

capisco perché questo errore accade con MyOptional, quello che don' t capire è perché non succede con Optional.

+2

Sospetto che la risposta sia "magia del compilatore". – jtbandes

+2

Avevo paura:/In tal caso, considerando che è open source, dov'è quella magia? – fpg1503

+0

Non sicuro; il codebase è piuttosto grande. Punto di partenza: https://github.com/apple/swift/search?utf8=%E2%9C%93&q=optional+covariant – jtbandes

risposta

3

E non lo fa. Swift non supporta generici covarianti personalizzati per ora.

Il correttore di tipo Swift è per espressione, non globale (come in Haskell). Questa attività è handled by l'analisi semantica in lib/Sema. Quindi il sistema di vincoli prova a match the types e i casi speciali di covarianza vengono quindi gestiti per collections e optionals.

Questa è stata una decisione di progettazione linguistica. Dovresti essere in grado di fare tutto il necessario con i tipi e gli accessori di raccolta integrati. Se non lo sei, dovresti probabilmente aprire un radar.

0

Mentre sono d'accordo sul fatto che ci sia probabilmente un "magico per il compilatore" in corso, questo può essere realizzato nella tua implementazione personalizzata mediante il cast del pulsante su un UIView, ad es.

var myOptionalButton = MyOptional.Some(button as UIView) 

o

var myOptionalButton: MyOptional<UIView> = .Some(button) 
Problemi correlati