2015-05-06 20 views
8

Ostatnio czytałem Protocols, Generic Type Constraints and Arrays in Swift. Moje pytanie dotyczy dwóch przykładów z bloga:Zachowanie protokołów z Self

Kod:

protocol MyProtocol1 { 
    var myValue: Self { get } 
} 

let array: [MyProtocol1] = [] // Error. 

Produkuje błąd:

Protocol 'MyProtocol1' can only be used as a generic constraint because it has Self or associated type requirements.

To się spodziewać i było kilka SO pytania dotyczące tematu. Jednakże, zmieniając myValue na funkcję, nie ma już żadnego błędu, ale w obu przypadkach zwracana jest nazwa Self.

protocol MyProtocol2 { 
    func myValue() -> Self 
} 

let array: [MyProtocol2] = [] // This is okay. 

Czy ktoś zna przyczynę tego pozornie dziwnego zachowania?

+0

Polecam omawianie tego na devforums. Podejrzewam, że jest to sprawa kątowa i może nie być zamierzona. Twórcy Swift są znacznie bardziej skłonni do udzielenia ostatecznej odpowiedzi. –

+0

Czy w końcu znalazłeś odpowiedź na to zachowanie? – bartzy

Odpowiedz

0

Nie mam na to jednoznacznej odpowiedzi, ale uważam, że może to wynikać z rozmiaru klasy i układu wewnętrznego.

Posiadanie skojarzonego typu lub członu typu Self wpłynie na rozmiar obiektu, a tym samym na rozmiar tablicy, ale użycie typu powrotu jako metody spowoduje zmianę wielkości obiektu.

+0

To interesujący pomysł, ale jeśli to prawda, można by się spodziewać, że boksujący "Self" to naprawi. Na przykład, jeśli zadeklarowałeś 'var myValue: Self? {get} '. Spowoduje to umieszczenie nieznanego rozmiaru 'Self' wewnątrz znanego rozmiaru' Opcjonalnie' i naprawi problem z układem. (Ta technika jest używana na przykład do rekurencyjnych wyliczeń, które mają ten problem z rozmiarem). Ale to nie pomaga. –

2

To wyjaśnia około 18 minut, w tym wideo: https://developer.apple.com/videos/wwdc/2015/?id=408

Ponieważ twoje referencje Protocol „ja” może być używany tylko jako ogólne ograniczenie nie jako typ.

Przykład: Załóżmy, że 2 konstrukcje implementują Twój protokół - Duke & Silver.

Jeśli utworzyłeś tablicę protokołu 2 ([protokół 2]), to tablica może zawierać albo Diuków, albo Silversów.

myValue określa, że ​​zwracana wartość musi być self. Oznacza to, że książę musi zwrócić księcia, a srebro musi oddać srebro. W związku z tym nie można uzyskać silniki Dukes & w tej samej tablicy, ponieważ ich funkcje MyValue mają różne wartości zwracane.

Aby rozwiązać ten problem, można:

1) Sprawdź typ zwracanej myValue protocol2 tak, Dukes i Silvers zarówno po prostu wrócić typ protocol2

2) Sprawdź tablicę leków generycznych, które są zgodne do protokołu2

+0

Brakowało ci punktu pytania. Protokół z właściwością typu 'Self' -' var myValue: Self {get set} '- będzie miał" wymagania własne lub powiązane typy "i będzie mógł być użyty tylko jako ograniczenie typu. Natomiast protokół z funkcją zwracającą wartość typu 'Self' -' func myValue() -> Self' - może być używany jako typ, a nie tylko jako ograniczenie typu.Zastanawiające pytanie brzmi: dlaczego właściwość protokołu * właściwość typu 'Self' ma inne zachowanie niż wymaganie funkcji * protokołu *, które zwraca wartość typu' Self'. –

+0

Ah, w rzeczy samej. Nie przeczytałem dokładnie tego pytania. Dziękuję Ci. – JoeyBartez