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

时间:2018-10-21 12:10:11

标签: swift generics protocols xcode10

使用游乐场并给出以下定义:

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 个答案:

答案 0 :(得分:1)

好吧...使用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
}

答案 1 :(得分:1)

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

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是实际实现类型的占位符。