2016-03-22 8 views
2

Ich versuche, ein einfaches Beobachter Mixen mit Swift 2 zu bauen. Hier kommt nur die relevanten Teil.Swift Generics im Protokoll: operator '===' kann nicht auf Operanden vom Typ '_' und 'Self.T' angewendet werden

protocol Observable{ 

    typealias T 
    var observers:[T] { get set } 
    mutating func removeObserver(observer:T) 
} 

Um die mixin ich eine Erweiterung erstellen verwenden:

extension Observable{ 

    mutating func removeObserver(observer:T){ 
     let index = self.observers.indexOf{ $0 === observer } 
     if let _ = index{ 
      self.observers.removeAtIndex(index) 
     } 
    } 
} 

Dies erzeugt der Compiler-Fehler: Binary operator '===' cannot be applied to operands of type '_' and 'Self.T'

Können Sie mir erklären, warum dieser Fehler auftritt?

Antwort

2

Die „gleich zu“ -Operator === kann nur auf Referenz Typen, d.h. Instanzen eines class angewendet werden. Eine mögliche Lösung ist auf beschränken den generischen Typ T-AnyObject (das Protokoll zu dem alle Klassen implizit konform):

protocol Observable { 

    typealias T : AnyObject 
    var observers:[T] { get set } 
    mutating func removeObserver(observer:T) 
} 

extension Observable { 

    mutating func removeObserver(observer:T) { 
     if let index = (self.observers.indexOf { $0 === observer }) { 
      self.observers.removeAtIndex(index) 
     } 
    } 
} 

Alternativ beschränken T zu Equatable Typen (was bedeutet, dass ein == Betreiber muss definiert werden für den Typ):

protocol Observable { 

    typealias T : Equatable 
    var observers:[T] { get set } 
    mutating func removeObserver(observer:T) 
} 

extension Observable { 

    mutating func removeObserver(observer:T) { 
     if let index = self.observers.indexOf(observer) { 
      self.observers.removeAtIndex(index) 
     } 
    } 
} 
+0

Danke für die Antwort. Ich habe es akzeptiert, weil es offensichtlich die Antwort auf meine Frage ist :) Leider löst es mein Problem nicht vollständig. Angenommen, ich definiere ein 'Protokoll'' Observer', das 'AnyObject' implementiert. Als nächstes erstelle ich eine Klasse 'ConcreteObservable', die' Observable' implementiert. Ich definiere 'typalias T = Observer'. Ich bekomme den folgenden Fehler: 'Typ 'ConcreteObservable' entspricht nicht dem Protokoll 'Observable'' ' Protokoll erfordert verschachtelten Typ' T'' und 'Möglicherweise beabsichtigte Übereinstimmung 'T' (alias 'Observer') nicht konform zu 'AnyObject'' Irgendwelche Ideen, wie das zu beheben? – hendra

+0

@hendra: Sie müssen Ihre Klasse generisch machen: 'Klasse ConcreteObservable : Observable {...}'. –

+0

Hm das macht für mich keinen Sinn. Wenn ich diese Klasse als generisch definieren würde wie Sie traurig, müsste ich während der Initialisierung von 'ConcreteObservable' einen konkreten Typ eines' Observer' deklarieren. Aber jedes Objekt, das "Beobachter" entspricht, sollte in der Lage sein, mein 'ConcreteObservable' zu ​​beobachten. Oder habe ich etwas falsch gemacht? – hendra