2016-05-20 11 views
11

W jaki sposób kowariancja działa dla Swift w sieciach Optional?Jak działa opcjonalna kowariancja w Swift

Say I napisać następujący kod:

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

nativeOptionalView = nativeOptionalButton 

kompiluje i działa dobrze. Jednak gdybym określić MyOptional jak

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

I napisać następujące:

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

myOptionalView = myOptionalButton 

pojawia się błąd:

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

rozumiem dlaczego to błędy dzieje z MyOptional, co I don” Rozumiemy, dlaczego tak się nie stało z Optional.

+2

Podejrzewam, że odpowiedź brzmi "magia kompilatora". – jtbandes

+2

Bałem się tak:/w takim przypadku, biorąc pod uwagę, że jest to open source, gdzie jest ta magia? – fpg1503

+0

Nie jestem pewien; kod jest dość duży. Punkt początkowy: https://github.com/apple/swift/search?utf8=%E2%9C%93&q=optymatywny+covariant – jtbandes

Odpowiedz

3

nie. Swift na razie nie obsługuje niestandardowych generali kowariancji.

Sprawdzanie typu Swift jest wyrażeniem, nie globalnym (jak w Haskell). Zadanie to to handled by analiza semantyczna w lib/Sema. System ograniczeń próbuje następnie match the types, a szczególne przypadki kowariancji są następnie obsługiwane dla collections i optionals.

To była decyzja dotycząca projektowania języka. Powinieneś być w stanie zrobić wszystko, czego potrzebujesz z wbudowanymi typami kolekcji i opcjami. Jeśli nie jesteś, prawdopodobnie powinieneś otworzyć radar.

0

Chociaż zgadzam się, że prawdopodobnie istnieje jakaś "magia kompilacyjna", można to osiągnąć w niestandardowej implementacji, przesyłając przycisk do UIView, np.

var myOptionalButton = MyOptional.Some(button as UIView) 

lub

var myOptionalButton: MyOptional<UIView> = .Some(button) 
Powiązane problemy