在rxswift Getter函数中使用Swift Generic-各种问题



这是函数:

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 s集合(字符串,INT等)。Element对这些类型的类型构成了一般性,但这造成了两个问题:

  1. distinctUntilChanged坚持要关闭(例如:如果此方法返回Driver<String>,则只需使用distinctUntilChanged(),但是通用的Element使其抱怨缺少闭合);
  2. 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线上

您可以使用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())
}

最新更新