【问题标题】:Passing self as argument to a Protocol function that wants same type as self as the argument将 self 作为参数传递给想要与 self 相同类型作为参数的协议函数
【发布时间】:2015-09-21 20:13:35
【问题描述】:

我正在编写一个异步字典,它返回一个 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?,因为

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

所以我发现自己陷入了困境,无法将自己作为参数传递,也无法设置委托来从该协议获取数据调用。我错过了什么吗?我愿意做 Swift 2 Voodoo。

玩具示例的内容(没有 Futures 和字典等)如下:

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)?
}

【问题讨论】:

    标签: swift generics delegates swift2 swift-protocols


    【解决方案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)
        }
    }
    

    【讨论】:

    • 啊,所以你让 Delegate 不是泛型的,而是将泛型约束放在方法上。这是一种解决方法,但它有效!非常感谢。
    • 实际上,我自己的实现对我不起作用,调用作为通用自动完成,并且它不接受我的参数。我想我只是将 dataCall 作为初始化程序传递,以便结构是自记录的。感谢您的解决方法,但我完全错过了重点:(
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 2021-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      相关资源
      最近更新 更多