Design patterns Swift 3中的协议扩展和泛型。这可能吗?

Design patterns Swift 3中的协议扩展和泛型。这可能吗?,design-patterns,swift3,Design Patterns,Swift3,我在阅读,我试图在一个快速的操场上复制设计模式。我试图让观察者模式按照书中的方式工作。 我目前的来源如下: protocol Subject { func register(observer: Observer) func remove(observer: Observer) func notifyObservers() } protocol Observer { func update(temperature: Double, humidity: Double

我在阅读,我试图在一个快速的操场上复制设计模式。我试图让观察者模式按照书中的方式工作。 我目前的来源如下:

protocol Subject {
    func register(observer: Observer)
    func remove(observer: Observer)
    func notifyObservers()
}

protocol Observer {
    func update(temperature: Double, humidity: Double, pressure: Double)
}

protocol DisplayElement {
    func display()
}

class WeatherData: Subject {
    
    var observers: [Observer]
    
    var temperature: Double!
    var humidity: Double!
    var pressure: Double!
    
    init() {
        observers = []
    }
    
    func register(observer: Observer) {
        observers.append(observer)
    }
    
    func remove(observer: Observer) {
    
    }
    
    func notifyObservers() {
        for obs: Observer in observers {
            obs.update(temperature: temperature, humidity: humidity, pressure: pressure)
        }
    }
}
我需要做的是实现removeObserver方法。我需要实现的代码片段如下:

func remove(observer: Observer) {
    let obs: Observer = observers.index(where: { (aObserver) -> Bool in
        return aObserver == observer
    })
}
但是,由于编译错误,这不允许我继续:

无法将类型为“(OptionalNilComparisonType)->Bool”的值转换为预期的参数类型“()->Bool”
甚至有可能做到这一点吗?我做错了什么?

无法测试任意对象是否相等。在Swift中,有许多类型的对象很难甚至不可能完全相等(一般来说,在大多数流行语言中;Swift只是比许多其他语言更明确地解决了这个问题)。有,但在您的例子中,您很可能是指观察者是类的某个特定实例,一个引用类型,而不是一个值。例如,数字4可能不允许作为观察者。这是Swift中可能发生的事情,所以您需要告诉Swift它在这里是不合法的,因为4是一个值,而不是一个引用

好的,足够的背景知识。你是怎么做到的?首先,假设观察者必须是类(即引用类型)

现在,你可以说“如果这个物体与观察者是完全相同的物体”,这与“如果这个物体与观察者相等”完全不同:

请注意此处使用的是
==
,而不是
=


有许多其他方法可以解决这个一般问题,但这是最符合观察者模式的方法。

无法测试任意对象是否相等。在Swift中,有许多类型的对象很难甚至不可能完全相等(一般来说,在大多数流行语言中;Swift只是比许多其他语言更明确地解决了这个问题)。有,但在您的例子中,您很可能是指观察者是类的某个特定实例,一个引用类型,而不是一个值。例如,数字4可能不允许作为观察者。这是Swift中可能发生的事情,所以您需要告诉Swift它在这里是不合法的,因为4是一个值,而不是一个引用

好的,足够的背景知识。你是怎么做到的?首先,假设观察者必须是类(即引用类型)

现在,你可以说“如果这个物体与观察者是完全相同的物体”,这与“如果这个物体与观察者相等”完全不同:

请注意此处使用的是
==
,而不是
=


有许多其他方法可以解决这个一般性问题,但这是最符合观察者模式的方法。

如果让Observer index=obsers.index(其中:{$0==obsers}){//在此处使用Observer index},请尝试
if let syntax的错误与您的协议观察者不符合的错误相同Equatable@LeoDabus我尝试遵守Equatable协议,但我遇到了以下几个错误:“协议‘Observer’只能用作一般约束,因为它具有自身或关联的类型需求”。另外,我不希望观察者成为一个结构,因为我希望每个对象都能够成为一个观察者,而无需扩展,但具有一致性。无法使其工作。有几个不同的错误。似乎我无法在具有默认行为的协议中重新定义==运算符try
如果let observer index=observer.index(其中:{$0==observer}){//use observer index here}
如果您的协议观察者不符合Equatable@LeoDabus我试着遵守平等协议,但我得到了一些这样的错误:“协议‘Observer’只能用作泛型约束,因为它具有自身或关联的类型需求”。另外,我不希望观察者成为一个结构,因为我希望每个对象都能够成为一个观察者,而无需扩展,但具有一致性。无法使其工作。有几个不同的错误。似乎我无法在具有默认行为的协议中重新定义==运算符
protocol Observer: class {
func remove(observer: Observer) {
    if let index = observers.index(where: { (aObserver) -> Bool in
        return aObserver === observer
    }) {
        observers.remove(at: index)
    }
}