代码之家  ›  专栏  ›  技术社区  ›  Aaron Bratcher

调用协议静态方法时无法推断泛型参数

  •  2
  • Aaron Bratcher  · 技术社区  · 7 年前

    使用操场并给出以下定义:

    import Foundation
    
    protocol MoneyTrakObject {
        var key: String { get set }
    
        init()
    }
    
    extension MoneyTrakObject {
        static func objectFromDB<T: MoneyTrakObject>(for key: String, queue: DispatchQueue? = nil, completion: @escaping (T) -> Void) -> String? {
                // after data is retrieved, call completion closure
                let valueObject = T()
                completion(valueObject)
    
            return "dbToken"
        }
    }
    
    
    protocol Transaction: MoneyTrakObject {
        var amount: Int { get set }
    }
    
    
    struct BasicTransaction: Transaction {
        var key = UUID().uuidString
        var amount = 0
    
        init() {}
    }
    
    struct RecurringTransaction: Transaction {
        var key = UUID().uuidString
        var amount = 0
    
        init() {}
    }
    

    我希望我能做到:

    let token1 = BasicTransaction.objectFromDB(for: "") { (transaction) in
        // use transaction
    }
    
    let token2 = RecurringTransaction.objectFromDB(for: "") { (transaction) in
        // use transaction
    }
    

    但是我得到了 Generic parameter 'T' could not be inferred 调用静态方法时出错,我不确定原因。

    2 回复  |  直到 7 年前
        1
  •  1
  •   J. Doe    7 年前

    我不明白为什么需要通用约束。如果您将协议扩展更改为:

    extension MoneyTrakObject {
        static func objectFromDB(for key: String, queue: DispatchQueue? = nil, completion: @escaping (Self) -> Void) -> String? {
            // after data is retrieved, call completion closure
            let valueObject = Self()
            completion(valueObject)
    
            return "dbToken"
        }
    }
    

    你的代码编译得很好。 Self 是实际实现类型的占位符。

        2
  •  1
  •   Code Different    7 年前

    好。。。唯一的地方 T 在完成处理程序参数内使用。当你写这个的时候:

    let token1 = BasicTransaction.objectFromDB(for: "") { (transaction) in
        // use transaction
    }
    

    编译器不知道什么类型 transaction 因此不能专门化泛型函数。提供如下类型的信息:

    let token1 = BasicTransaction.objectFromDB(for: "") { (transaction: Transaction) in
        // use transaction
    }
    
    let token2 = BasicTransaction.objectFromDB(for: "") { (transaction: BasicTransaction) in
        // use transaction
    }
    
    推荐文章