swift 3 : Nested Generic Type

标签 swift generics types

当我尝试从 Swift 2 迁移我的代码时,我无法弄清楚编译器的一些奇怪行为(Xcode 8、Swift 3)。我认为这与元组有关,但我我并不完全确定。

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

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

在分配时 (letendingRequest: Request = ...),我收到此错误:

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

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

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

最佳答案

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

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

然后编译器指出

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

which reveals the actual problem: The cb parameter must be marked as @escaping because it is stored in a property and might be called at a later time, after returning from the request method:

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 .

关于 swift 3 : Nested Generic Type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39711381/

相关文章:

swift - associatedType 的值可以是协议(protocol)吗?

c# - C# 中的 ref 与 out

c++ - C++ 中的奇怪类型

swift - 无法将类型 'GenericTableViewController<T, U>' 的值分配给类型 'GenericTableViewController<GenericTableViewCell<_>, _>'

swift - 在 View Controller 生命周期中的何处添加 subview

arrays - 序列化异构数组

swift - 如何访问公共(public)常量而不必像在 C# 中那样实例化类

java - 模板和泛型。为什么我可以在 C++ 中执行以下操作,但不能在 Java 中执行?我该如何克服这个问题?

excel - Excel 2007 的 Mime 类型

swift - 实现相同协议(protocol)的不同结构的重载函数?