2016-04-23 16 views
2
protocol A {} 
protocol B { 
    var a: A { get } 
} 

struct StructA: A {} 
struct StructB { 
    var a: StructA 
} 
extension StructB: B {} 

Dies erzeugt den Fehler:Swift: Typ nicht entspricht Protokoll

Typ 'StructB' nicht zu Protokoll 'B' zu Protokoll

Die StructA bereits entsprechen nicht konform A und StructB 's Eigenschaft a zurück StructA Typ. Das scheint ein Protokoll B ähnlicher Art zu sein.

Aber warum?


Xcode-Version 7.3, die Swift-Version 2.2

+0

Konnten Sie versuchen 'a = StructA()'. – Khuong

Antwort

3

besser, um das Problem mit dem aktuellen Code veranschaulichen, lassen Sie uns sagen, dass Sie eine StructC : A haben.

Ihr Protokoll B sagt, dass Sie StructC-a zuweisen können (wie es A entspricht) - aber StructB sagt man nicht StructC zu einem StructA Typ zuordnen. Daher entspricht StructB nicht B.

Die Lösung ist entweder die Art der aStructA-Aas Rahul says, oder besser noch zu ändern, könnten Sie Generika verwenden.

Der Vorteil der Verwendung von Generika ist, sobald Sie Ihre StructB mit einem gegebenen a erstellen - dieser Eigenschaftstyp wird von Swift abgeleitet, was Ihnen bessere Typensicherheit gibt. Wenn Sie ihm beispielsweise StructA zuweisen, ist sein Typ StructA. Wenn Sie ihm eine StructC zuweisen, ist sein Typ StructC.

Dazu müssen wir nur ein associatedtype Protokoll B hinzufügen. Dies definiert einen 'Platzhalter'-Typ, den wir dann in einem Typ implementieren können, der B entspricht. Wir können dann den generischen Typ T in StructB definieren, der die 'Implementierung' von AType bereitstellt - sicherstellen, dass sie A entspricht. Daher können wir jetzt entweder StructA oder StructC zu a zuweisen, ohne die Typsicherheit zu verlieren.

protocol A {} 
protocol B { 

    // new associated type to hold the type of "a" which conforms to A 
    associatedtype AType:A 
    var a: AType { get } 
} 

struct StructA: A {} 
struct StructC:A {} 

// define the new generic T which conforms to A 
struct StructB<T:A> { 

    // define the type of a as the generic T, which conforms to A (and thus conforms with the protocol) 
    var a : T 
} 

extension StructB: B {} 

let s = StructB(a: StructA()) 
s.a // "a" is now of type StructA 

let s1 = StructB(a: StructC()) 
s1.a // "a" is now of type StructC 
2

ist Da Swift statisch typisiert ist und hängt nicht von dynamischen Dispatch. Sie könnten etwas wie unten tun.

import UIKit 

protocol A {} 
protocol B { 
    var a: A { get } 
} 

struct StructA: A {} 
struct StructB { 
    var a: A = StructA() 
} 
extension StructB: B {} 
+1

nur eine Anmerkung: es ist nicht notwendig, dass var a: A einen Standardwert hat ... – user3441734

Verwandte Themen