功能如下:
func registerFor<Element>(relayId id: String) -> Driver<Element>? {
guard let relay = relays[id] as? BehaviorRelay<Element> else { return nil }
return relay.asObservable()
.distinctUntilChanged { a, b in
return a != b
}.flatMapLatest { value in
return Observable.create { observer in
observer.on(.next(value))
return Disposables.create()
}
}.asDriver(onErrorJustReturn: Element())
}
distinctUntilChanged
行引发以下错误:
Contextual closure type '(Element) throws -> _' expects 1 argument,
but 2 were used in closure body
asDriver
行引发了以下错误(当然):
Non-nominal type 'Element' does not support explicit initialization
上下文:理想情况下,我有一个类,其中包含各种类型(字符串,整数等)的BehaviorRelay
的集合。 Element
通常代表这些类型,但这会带来两个问题:
distinctUntilChanged
坚持要闭包(例如:如果此方法返回了Driver<String>
,那么简单地使用distinctUntilChanged()
就可以满足要求,但是通用Element
使其抱怨丢失关闭); onErrorJustReturn
需要一个具体值,但是Element
是通用的。以下“解决方法”可能有效,但我怀疑有更好的解决方案
protocol Inii {
init()
}
func registerFor(relayId id: String, def: Inii.Type) -> Driver<Inii>? {
return relays[id]?.asObservable()
.distinctUntilChanged { _, _ in
return true
}.flatMapLatest { value in
return Observable.create { observer in
observer.on(.next(value))
return Disposables.create()
}
}.asDriver(onErrorJustReturn: def.init())
}
尽管我仍然不确定要放在distinctUntilChanged
闭包中的内容。
附录A
我认为,如果要为非通用类型实现distinctUntilChanged
闭包,则需要满足以下条件:
.distinctUntilChanged { previousValue, currentValue in
return previousValue == currentValue
}
但是,当与通用Element
一起使用时,仍然会引发以下错误:
Contextual closure type '(Inii) throws -> _' expects 1 argument,
but 2 were used in closure body
附录B
这里是另一种问题稍有不同的选择:
protocol Inii {
init()
}
var relay = BehaviorRelay<String>(value: "")
func registerFor<Element>(def: Element.Type) -> Driver<Element> where Element: Inii {
return relay.asObservable()
.distinctUntilChanged { previousValue, currentValue in
return previousValue == currentValue
}.flatMapLatest { value in
return Observable.create { observer in
observer.on(.next(value))
return Disposables.create()
}
}.asDriver(onErrorJustReturn: def.init())
}
在这种情况下的错误是:
Member 'next' in 'Event<_>' produces result of type 'Event<Element>',
but context expects 'Event<_>'
在observer.on
行
答案 0 :(得分:1)
只要distinctUntilChanged()
符合Element
,就可以使用Equatable
而不用闭包:
protocol EmptyInit {
init()
}
func registerFor<Element>(relayId id: String) -> Driver<Element>? where Element: Equatable, Element: EmptyInit {
guard let relay = relays[id] as? BehaviorRelay<Element> else { return nil }
return relay.asObservable()
.distinctUntilChanged()
.flatMapLatest { value in
return Observable.create { observer in
observer.on(.next(value))
return Disposables.create()
}
}.asDriver(onErrorJustReturn: Element())
}