【问题标题】:Swift generics in protocol: operator '===' cannot be applied to operands of type '_' and 'Self.T'协议中的 Swift 泛型:运算符“===”不能应用于“_”和“Self.T”类型的操作数
【发布时间】:2016-03-22 17:37:37
【问题描述】:

我正在尝试使用 Swift 2 构建一个简单的观察者 mixin。 这里只是相关部分。

protocol Observable{

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

为了创建 mixin,我使用了一个扩展:

extension Observable{

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

这会产生编译器错误:Binary operator '===' cannot be applied to operands of type '_' and 'Self.T'

你能解释一下为什么会出现这个错误吗?

【问题讨论】:

    标签: swift generics swift-extensions swift-protocols


    【解决方案1】:

    “identical-to”运算符=== 只能应用于引用 类型,即class 的实例。一种可能的解决方案是 将泛型类型 T 限制为 AnyObject(协议 所有类都隐式符合):

    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)
            }
        }   
    }
    

    或者,将 T 限制为 Equatable 类型(这意味着 必须为该类型定义 == 运算符):

    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)
            }
        }   
    }
    

    【讨论】:

    • 感谢您的回答。我接受了它,因为它显然是我问题的答案 :) 遗憾的是,它并没有完全解决我的问题。假设我定义了一个实现AnyObjectprotocol Observer。接下来我创建一个实现Observable 的类ConcreteObservable。我定义typealias T = Observer。我收到以下错误:Type 'ConcreteObservable' does not conform to protocol 'Observable' Protocol requires nested type 'T'Possibly intended match 'T' (aka 'Observer') does not conform to 'AnyObject' 有关如何解决此问题的任何想法?
    • @hendra:你必须让你的类通用:class ConcreteObservable<T : Observer> : Observable { ... }
    • 嗯,这对我来说真的没有意义。如果我像你一样将这个类定义为泛型,我需要在ConcreteObservable 的初始化过程中声明一个具体的Observer 类型。但是任何符合Observer的对象都应该能够观察到我的ConcreteObservable。还是我做错了什么?
    • @hendra:问题在于Observable 协议不符合AnyObject,即使它继承自该协议:请参阅stackoverflow.com/questions/33112559/…,也许这有帮助.
    • Observable 协议真的需要定义吗,我应该如何存储Observer 的? @MartinR
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多