在函数定义中将泛型类型定义为协议类型

Define a generic type as protocol type in function definition

我想要一个视图函数,returns 第一个匹配给定类型的 UIResponder:

extension UIView {
  func responder<T, Result: UIResponder & T>(ofType: T) -> Result? {
    var parentResponder: UIResponder? = self
    while parentResponder != nil {
      parentResponder = parentResponder?.next
      if let matchingResponder = parentResponder as? Result {
        return matchingResponder
      }
    }
    return nil
  }
}

不幸的是,编译器显示以下错误:

Non-protocol, non-class type 'T' cannot be used within a protocol-constrained type

我的问题很简单:如何告诉编译器 T 是协议类型?

不需要两个参数,一个就够了。您还可以为 type 参数提供默认值,以防编译器可以推断出结果:

extension UIView {
    func findResponder<T>(ofType type: T.Type = T.self) -> T? {
        func find(_ current: UIResponder) -> T? {
            if let result = current as? T { return result }
            guard let next = current.next else { return nil }
            return find(next)
        }
        return find(self)
    }
}

请注意,您不能将 T 限制为仅协议,因为在 Swift 中协议不是第一个 class 类型。但是你不应该需要这个。

我还将方法实现重新组织为更实用的样式。

用法:

let dataSource = view.findResponder(ofType: UITableViewDataSource.self)
let navCtrl: UINavigationController = view.findResponder()