【发布时间】:2019-03-28 02:08:39
【问题描述】:
我想为观察者模式设计一个通用的 Swift 协议,以用于不同的类型/类。问题是我似乎无法为观察者的notify() 方法指定类型。
最初,我尝试使用我的Observer 协议创建一个associatedtype。
protocol Observer {
associatedtype T
func notify(_ value: T)
}
protocol Observable {
var observers: [Observer] { get set }
func registerObserver(_ observer: Observer)
func unregisterObserver(_ observer: Observer)
}
这不起作用(编译错误):error: protocol 'Observer' can only be used as a generic constraint because it has Self or associated type requirements。
所以我尝试改用泛型方法:
protocol Observer {
func notify<T>(_ value: T)
}
protocol Observable {
associatedtype T
var observers: [Observer] { get set } // This is okay now
}
extension Observable {
// implement registerObserver()
// implement unregisterObserver()
func notifyObservers<T>(_ value: T) {
for observer in observers {
observer.notify(value)
}
}
}
这很好用,但会产生一些非常有趣的结果。为了测试它,我创建了FooObserver 和FooObservable:
class FooObserver: Observer {
func notify<T>(_ value: T) {
print(value)
}
}
class FooObservable: Observable {
typealias T = Int // For simplicity I set T to Int type
var observers: [Observer] = []
}
let a = FooObserver()
let b = FooObserver()
var c = FooObservable()
c.registerObserver(a)
c.registerObserver(b)
c.notifyObservers("hello") // This works, but why?
我能够成功地通知我的 2 个观察者字符串“hello”。我猜这与类型擦除有关...?
所以我的问题是:如何实现泛型类型的观察者模式,我可以确定notify() 中的值是正确的类型?
【问题讨论】:
标签: swift generics protocols observer-pattern