调用协议静态方法时无法推断泛型参数
Could not infer generic parameter when calling protocol static method
使用游乐场并给出这些定义:
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
错误,我不确定为什么。
嗯...唯一使用 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
}
我不明白您为什么需要通用约束。如果您将协议的扩展名更改为此:
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
是实际实现类型的占位符。
使用游乐场并给出这些定义:
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
错误,我不确定为什么。
嗯...唯一使用 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
}
我不明白您为什么需要通用约束。如果您将协议的扩展名更改为此:
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
是实际实现类型的占位符。