我有一个通过PrimaryKey获取数据库对象的协议
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)产生以下错误:
如果没有更多的上下文,表达的类型是不明确的
我试图解决的问题是如何让编译器认识到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)生成错误:
&#39; [PrimaryKeyConvertible]&#39;不能兑换为[GoogleContact]&#39;
答案 0 :(得分:0)
嗯,虽然我不太确定问题是什么,但我认为以下实施可能就是你想要的。
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) }
}
}
}