gpt4 book ai didi

swift - 在 Value 是 Array 的情况下扩展 SignalProducerType

转载 作者:行者123 更新时间:2023-11-28 08:43:20 25 4
gpt4 key购买 nike

我有一个通过主键获取数据库对象的协议(protocol)

typealias PrimaryKey = String

protocol PrimaryKeyConvertible {
var pkValue : PrimaryKey { get }
static func pkObject(key: PrimaryKey) -> Self?
}

并且我想扩展 SignalProducerType 以便能够对该类型的 SignalProducer.Value 进行操作。

因此,单个对象扩展(单个而不是数组)工作正常并按如下方式实现:

extension SignalProducerType
where Value: PrimaryKeyConvertible
{
func fetchOnMainThread() -> SignalProducer<Value?, Error> {
return
self.map{ (obj: Value) -> PrimaryKey in
return obj.pkValue
}
.observeOn(UIScheduler())
.map{ (key: PrimaryKey) -> Value? in
return Value.pkObject(key)
}
}
}

但是当我尝试在这些元素的数组上实现它时,我遇到了一些编译挑战:

extension SignalProducerType
{
func fetchOnMainThread<P: PrimaryKeyConvertible where Self.Value == Array<P>>() -> SignalProducer<[P], Error> { //(1)
return self.map({ (value: Self.Value) -> [PrimaryKey] in
return value.map{ $0.pkValue } //(2)
})
}
}

(1) 我怀疑签名没有正确地将想法传达给编译器

(2) 产生以下错误:

Type of expression is ambiguous without more context

我要解决的问题是如何让编译器识别 SignalProducer 正在 Array<P> 上运行其中 P 是 PrimaryKeyConvertible 并且有 .map相应地对其进行操作......

我目前对数组问题的解决方案是使用下面列出的通用函数来实现:

func fetchOnMainThread<Value: PrimaryKeyConvertible, Error: ErrorType>
(signal: SignalProducer<[Value], Error>) -> SignalProducer<[Value], Error> {
return signal
.map{ (convertibles: [Value]) -> [PrimaryKey] in
return convertibles.map { $0.pkValue }
}
.observeOn(UIScheduler())
.map{ (keys: [PrimaryKey]) -> [Value] in
return keys.flatMap{ Value.pkObject($0) }
}
}

然后使用例如:

extension GoogleContact: PrimaryKeyConvertible {...}

extension GoogleContact {
static func fetchGoogleContactsSignal() -> SignalProducer<[GoogleContact], GoogleContactError> { ...}
}

调用站点会是这样的:

let signal = fetchOnMainThread(GoogleContacts.fetchGoogleContactsSignal()).onNext...

我更愿意把它作为一个扩展,让它像往常一样流动

GoogleContacts
.fetchGoogleContactsSignal()
.fetchOnMainThread()

更新

我试过的另一个版本的函数:(@J.Wang)

extension SignalProducerType
where Value == [PrimaryKeyConvertible]
{
func fetchArrayOnMainThread2<T: PrimaryKeyConvertible>() -> SignalProducer<[T], Error> {
return self
.map{ (values: Self.Value) -> [PrimaryKey] in
return values.map{ $0.pkValue }
}
.deliverOnMainThread()
.map{ (keys: [PrimaryKey]) -> [T] in
return keys.flatMap{ T.pkObject($0) }
}
}

}


let signal =
GoogleContacts
.fetchGoogleContactsSignal()
.fetchArrayOnMainThread2() //(3)

(3) 产生错误:

'[PrimaryKeyConvertible]' is not convertible to '[GoogleContact]'

最佳答案

嗯,虽然我不太确定问题出在哪里,但我认为以下实现可能是您想要的。

extension SignalProducerType where Value == [PrimaryKeyConvertible]
{
func fetchOnMainThread() -> SignalProducer<[PrimaryKey], Error> {
return self.map { value in
value.map { $0.pkValue }
}
}
}

试试这个:

extension SignalProducerType where Value == [PrimaryKeyConvertible]
{
func fetchOnMainThread<T: PrimaryKeyConvertible>() -> SignalProducer<[T], Error> {
return self.map { value in
value.map { $0.pkValue }
}.map { keys in
keys.flatMap { T.pkObject($0) }
}
}
}

关于swift - 在 Value 是 Array<SomeProtocol> 的情况下扩展 SignalProducerType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35930561/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com