Не удалось определить общий параметр при вызове статического метода протокола - PullRequest
0 голосов
/ 21 октября 2018

Используя игровую площадку и учитывая эти определения:

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 голосов
/ 21 октября 2018

Я не понимаю, зачем вам общее ограничение.Если вы измените расширение вашего протокола на это:

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 является заполнителем для фактически реализуемого типа.

0 голосов
/ 21 октября 2018

Ну ... единственное место, где используется 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...