2016-10-28 1 views
0

Das folgende erfundene Swift 2 Beispiel aus dem realen Welt Code kompiliert nicht:Wie strukturiert man die generische Protokollkonformität in Swift?

protocol SomeModelType { } 

protocol SomeProtocol { 
    var someVar: SomeModelType? { get } 
} 

class ConcreteClass<T: SomeModelType>: SomeProtocol { 
    var someVar: T? 
} 

Dieser Sinn für mich nicht in vollem Umfang machen. Ich würde in ConcreteClass davon ausgehen, dass, weil ich T müssen SomeModelType und haben für die someVar Eigenschaft T als Trägertyp beschränkt zu sein, würde der Compiler Lage sein, herauszufinden, dass die SomeProtocol durch ConcreteClass angepasst wurde.

Wie sollte ein solches Beispiel strukturiert sein? Ist es dem Swift-Compiler möglich, die Protokollkonformität über generische Typ-Constraints zu bestimmen?

+0

Verwandte (möglich Betrogene?): [Swift: Wie kann ich eine Funktion mit einem Subklassen-Rückgabetyp zu einem Protokoll entsprechen machen, wo eine übergeordneten Klasse als Rückgabetyp definiert ist] (http: // Stackoverflow com/questions/35094967/swift-wie-kann-ich-mache-eine-Funktion-mit-einer-Unterklasse-Rückgabetyp-conform-to-a-protoc) Ihr Problem hat sehr wenig mit Generika zu tun, es ist aufgrund der Tatsache, dass die Protokollanforderungen invariant erfüllt sein müssen (wie das verknüpfte Q & A sagt) - daher können Sie eine abstrakte Typanforderung nicht mit einem konkreten Typ erfüllen, der diesem abstrakten Typ entspricht. – Hamish

+0

Dies mag kontraintuitiv erscheinen, aber denken Sie daran, dass das Zulassen kovarianten Verhaltens für die Protokollkonformität mit kontravarianten Beziehungen bricht (z. B. Eigenschafteneinsteller und Methodeneingaben). Das Umwandeln einer 'ConcreteClass ' in 'SomeProtocol' würde ermöglichen, dass * alles *, das 'SomeModelType' entspricht, in Parameter eingegeben wird, die zuvor einen konkreten Typ hatten, was illegal wäre. – Hamish

Antwort

0
protocol SomeModelType { } 

protocol SomeProtocol { 

    associatedtype T: Any 
    var someVar: T? { get } 
} 

class ConcreteClass<T> :SomeProtocol where T: SomeModelType { 

    var someVar: T? 

} 
Verwandte Themen