将self作为参数传递给需要与self相同类型的Protocol函数作为参数

时间:2015-09-21 20:13:36

标签: swift generics delegates swift2 swift-protocols

我正在编写一个异步字典,它返回一个值为:

的Future
  • 如果已经缓存,则立即
  • 在(网络)操作之后,如果它还没有

我班级里面的字典是通用的,所以班级也是如此。目前,用户必须阅读文档并知道设置dataCall函数,这是字典知道如何获取密钥值的方式,格式为

var dataCall: ((key: Key) -> Future<Value, MyError>)?

但是这需要其他程序员知道数据调用并设置它。 所以我写了一个协议

protocol CacheDelegate {
    typealias T: Hashable
    typealias U
    func dataCallForCacheManager(cacheManager: CacheManager<T, U>) → (key: T) → Future<Value, MyError>
}

然而,如果我尝试在init()中将其称为

delegate.dataCallForCacheManager(self)

我收到错误

  

无法使用类型为'(CacheManager)'

的参数列表调用dataCallForDictionary

我也无法制作var delegate: CacheDelegate?,因为

  

协议CacheDelegate只能用作通用约束,因为它具有Self或关联类型要求。

所以我发现自己陷入困境,我无法将自己作为一个论点,我无法设置委托来从这个协议中获取数据。我错过了什么吗?我愿意做Swift 2 Voodoo。

玩具示例的内容(没有期货和字典以及所有内容)如下:

import Foundation

protocol Delegate {
    typealias T: Hashable
    typealias U
    func dataCallForDictionary(dictionary: MyDictionary<T, U>) -> (T) -> (U)
}

struct MyDictionary<Key: Hashable, Value> {
    typealias T = Key
    typealias U = Value

    init<Object: Delegate>(delegate: Object) {
        dataCall = delegate.dataCallForDictionary(self)
//        self.delegate = delegate
    }

    var delegate: Delegate?

    var dataCall: ((key: Key) -> Value)?
}

2 个答案:

答案 0 :(得分:1)

举个例子,你考虑过这样做:

protocol Delegate {
    func dataCallForDictionary<T: Hashable, U>(dictionary: MyDictionary<T, U>) -> T -> U
}

struct MyDictionary<Key: Hashable, Value> {
    var delegate: Delegate?
    var dataCall: ((key: Key) -> Value)?

    init(delegate: Delegate) {
        self.delegate = delegate
        dataCall = delegate.dataCallForDictionary(self)
    }
}

答案 1 :(得分:0)

我认为MyDictionary结构中的委托应该是弱的。