Swift 3中的协议扩展和泛型。 [英] Protocol extension and generics in Swift 3. Is this even possible?

查看:156
本文介绍了Swift 3中的协议扩展和泛型。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 Head First设计模式,我正在尝试在Swift Playground中复制设计模式。我正在尝试使《观察者》模式按照本书的要求工作。
我当前的来源如下:

I'm reading Head First Design Patterns and I'm trying to replicate the Design Patterns in a Swift Playground. I'm trying to get the Observer pattern working as per the book. My current source is as follows:

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方法。我需要实现的代码片段是:

What I need to do is to implement the removeObserver method. The snippet that I need to implement is something as:

func remove(observer: Observer) {
    let obs: Observer = observers.index(where: { (aObserver) -> Bool in
        return aObserver == observer
    })
}

但是由于编译错误,这不允许我继续:

However this is not allowing me to continue because of a compilation error:

是否有可能实现这一目标,而我在做什么错呢?

Is it even possible to achieve this and what am I doing wrong?

推荐答案

不能对任意对象进行相等性测试。在Swift中,很难确定甚至无法确定完全相等的对象种类很多(通常在大多数流行语言中,Swift比许多其他语言都更明确地解决了这个问题)。有解决此问题的方法很多,但是在您的情况下,您很可能是说观察者是某个类的特定实例,引用类型而不是值。例如,可能不允许数字4为观察者。在Swift中可能会发生这种情况,因此您需要告诉Swift这是不合法的,因为4是一个值,而不是引用。

Arbitrary objects are can not be tested for equality. There are many kinds of objects which full equality is difficult or even impossible to determine in Swift (and generally speaking in most popular languages; Swift just addresses this problem more explicitly than many other languages do). There are lots of ways to address this, but in your case you really likely mean that the observer is some specific instance of a class, a reference type, rather than a value. The number 4 is probably not allowed to be an observer, for instance. That's something that can happen in Swift, so you need to tell Swift that it isn't legal here because 4 is a value, not a reference.

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

OK, enough background. How do you do it? Well, first, say Observers have to be classes (i.e. reference types).

protocol Observer: class {

现在,您可以说如果该对象与观察者完全相同完全不同于如果这个东西等于观察者:

And now, you can say "if this object is exactly the same object as the observer" which is completely different than "if this thing is equal to the observer:"

func remove(observer: Observer) {
    if let index = observers.index(where: { (aObserver) -> Bool in
        return aObserver === observer
    }) {
        observers.remove(at: index)
    }
}

请注意使用 = == 而不是 ==

还有很多其他方法可以可以解决这个普遍的问题,但这是与观察者模式最匹配的方式。

There are lots of other ways to attack this general problem, but this is the way that best matches the Observer pattern.

这篇关于Swift 3中的协议扩展和泛型。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆