2015-05-06 11 views
8

Ich habe vor kurzem Protocols, Generic Type Constraints and Arrays in Swift gelesen. Meine Frage bezieht sich auf die folgenden zwei Beispiele aus dem Blog:Verhalten von Protokollen mit Selbst

Der Code:

protocol MyProtocol1 { 
    var myValue: Self { get } 
} 

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

Erzeugt den Fehler:

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

Das erwartet wird, und es wurden mehrere SO Fragen gewesen über das Thema. Wenn Sie jedoch myValue in eine Funktion ändern, tritt kein Fehler mehr auf. In beiden Fällen wird Self zurückgegeben.

protocol MyProtocol2 { 
    func myValue() -> Self 
} 

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

Kennt jemand die Ursache für diese scheinbar seltsame Verhalten?

+0

Ich empfehle, dies auf den devforums zu diskutieren. Ich vermute, dies ist ein Eckfall und möglicherweise nicht beabsichtigt. Die Swift-Entwickler geben eher eine definitive Antwort. –

+0

Haben Sie schließlich eine Antwort auf dieses Verhalten gefunden? – bartzy

Antwort

0

Ich habe keine definitive Antwort auf dieses, aber ich denke, dass dies aufgrund der Klassengröße und des internen Layouts sein kann.

Wenn Sie einen assoziierten Typ oder ein Self-Typ-Element haben, wirkt sich dies auf die Größe des Objekts und damit auf die Array-Größe aus.

+0

Das ist eine interessante Idee, aber wenn es wahr wäre, würdest du erwarten, dass das Boxen 'Self' es beheben würde. Zum Beispiel, wenn Sie 'var myValue: Self deklariert haben? {bekommen} '. Dies würde das "Self" in unbekannter Größe in eine "optionale" Größe bekannter Größe einfügen und das Layout-Problem beheben. (Diese Technik wird beispielsweise für rekursive Enums verwendet, die dieses Größenproblem haben.) Aber es hilft nicht. –

2

Es liegt ca. 18 Minuten in diesem Video erklärt: https://developer.apple.com/videos/wwdc/2015/?id=408

Da Ihr Protokoll Referenzen „Selbst“ nur als generische Einschränkung nicht als Typ verwendet werden kann.

Beispiel: Nehmen wir an, 2 Strukturen implementieren Ihr Protokoll - Duke & Silber.

Wenn Sie ein Array von protocol2 ([protocol2]) erstellt haben, könnte Ihr Array entweder Dukes silvers enthalten.

myValue gibt ausdrücklich an, dass der Rückgabewert self sein muss. Dies bedeutet, dass ein Herzog einen Herzog zurückgeben muss und ein Silber ein Silber zurückgeben muss. Als solche können Sie keine Duke & Silvers im selben Array haben, da ihre MyValue-Funktionen unterschiedliche Rückgabewerte haben.

Um das Problem zu beheben, können Sie entweder:

1) Stellen Sie den Rückgabetyp von myValue Protokoll2 so dass Dukes und Silvers beide nur einen Protokoll2 Typ zurückgeben

2) eine Reihe von Generika-Stellen, die konform zu protocol2

+0

Sie haben den Punkt der Frage verpasst. Ein Protokoll mit einer Eigenschaft vom Typ 'Self' -' var myValue: Self {get set} '- hat' Selbst- oder zugehörige Typanforderungen' und kann nur als Typbeschränkung verwendet werden. Im Gegensatz dazu kann ein Protokoll mit einer Funktion, die einen Wert vom Typ "Self" - "func myValue() -> Self" zurückgibt - als Typ und nicht nur als Typbeschränkung verwendet werden.Die rätselhafte Frage ist, warum eine Anforderung des Typs protocol * property * vom Typ self ein anderes Verhalten hat als eine Anforderung protocol * function *, die einen Wert vom Typ self zurückgibt. –

+0

Ah, tatsächlich. Ich habe die Frage nicht gründlich gelesen. Vielen Dank. – JoeyBartez

Verwandte Themen