Swift 3:嵌套通用类型

时间:2016-09-26 19:59:48

标签: swift generics types

我从编译器中得到一些奇怪的行为我无法弄清楚(Xcode 8,Swift 3),因为我正在尝试从Swift 2迁移我的代码。我认为它与元组有关,但是我我不完全确定。

我有一个定义了几个泛型的泛型类。在那些泛型中,我还有一些类型别名的设置和使用它们的函数:

open class GuardPool <Key: Hashable, Resource> {

  public typealias ResourceCallback = ([Resource]) -> Void
  public typealias Request = (keys: Set<Key>, cb: ResourceCallback)
  fileprivate var pendingRequests: [Request] = []

  open func request(_ keys: Set<Key>, cb: ([Resource]) -> Void) {
    let pendingRequest: Request = (keys: keys, cb: cb)
    pendingRequests.append(pendingRequest)
  }
}

在作业(let pendingRequest: Request = ...)上,我收到此错误:

Cannot convert value of type 'Set<Key>' to specified type 'Set<_>'

我无法弄清楚如何解决这个问题。似乎编译器无法识别Set的类型信息。

注意:显然,这个类要大得多。我复制并粘贴了相关代码,而不是插入300行。

1 个答案:

答案 0 :(得分:0)

错误消息具有误导性。如果你删除 第二行中的(不必要的)显式类型注释

    let pendingRequest = (keys: keys, cb: cb)

然后编译器声明

error: non-escaping parameter 'cb' may only be called
note: parameter 'cb' is implicitly non-escaping

显示实际问题:cb参数必须标记为@escaping因为 它存储在一个属性中,可能会在以后调用, 从request方法返回后:

open func request(_ keys: Set<Key>, cb: @escaping ([Resource]) -> Void) {
    let pendingRequest = (keys: keys, cb: cb)
    pendingRequests.append(pendingRequest)
}

在Swift 2中,默认情况下,闭包是逃避的,可以标记 与@noescape。在Swift 3中,默认情况下,闭包是非转义的, 比较SE-0103: Make non-escaping closures the default