Объявление свойства общего протокола - PullRequest
2 голосов
/ 29 марта 2019

Предположим, у меня есть протокол со связанным типом T

protocol Helper{
    associatedtype T
    func help(_ item: T)
}

в классе, я хочу объявить свойство

class Manager<T>{
    let item: T?
    let helper: Helper<T>
//Error: Cannot specialize non-generic type 'Helper'

    let anotherHelper: Helper 
//Error: Protocol 'Helper' can only be used as a generic constraint because it has Self or associated type requirements
}

Как объявить и использовать свойство helper таким образом, чтобы оно обеспечивало тип класса, соответствующий протоколу Helper?

Я уверен, что многие люди с опытом работы в Java / C # или других похожих языках застряли при попытке сделать похожие вещи

Ответы [ 2 ]

0 голосов
/ 29 марта 2019

Вам может понадобиться ластик типа:

struct AnyHelper<T>: Helper {
    private let helpFunc: (T) -> Void

    init<H>(_ helper: H) where Helper.T == T {
        helpFunc = helper.help
    }

    func help(_ item: T)
        helpFunc(item)
    }
}

, а затем использовать ластик типа в своем классе:

class Manager<T>{
    let item: T?
    let helper: AnyHelper<T>

    init<H>(item: T, helper: H) where H.T == T {
        self.item = item
        self.helper = AnyHelper(helper)
    }
}
0 голосов
/ 29 марта 2019

В этом конкретном случае вы могли бы сделать T в Manager<T> вместо Helper:

class Manager<T> where T : Helper {
    let item: T.T?
    let helper: T

    init(helper: T) {
        self.helper = helper
        item = nil
    }
}

И если вы хотите Helper<Int>, вы делаете:

class IntHelper : Helper {
    typealias T = Int

     // ... 
}

А затем используйте Manager<IntHelper>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...