У меня есть протокол моей быстрой базы кода У меня есть протокол со связанным типом и двумя методами. Оба метода определяют разные общие ограничения для связанного типа протокола. И я хотел бы, чтобы структура соответствовала двум протоколам, но с двумя разными связанными типами.реализовать протокол с другим связанным типом
protocol Convertable {
associatedtype TargetType
func convert() -> TargetType
}
func show<T : Convertable where T.TargetType == String>(toShow : T) {
print(toShow.convert())
}
func add<T : Convertable where T.TargetType == Int>(a : T, b : T) -> Int {
return a.convert() + b.convert()
}
struct MyData {
var data : Int
}
В качестве расширения я делаю структура соответствует протоколу, где TargetType
будет String
для того, чтобы передать его в метод показа:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
}
До сих пор все работает, как ожидалось. Но теперь мне также нравится, чтобы структура соответствовала протоколу Convertable
, когда TargetType
привязан к Int. Что кажется невозможным?
Первое, что я попытался было добавить второе определение метода новообращенного к расширению:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
func convert() -> Int { return data }
}
Теперь компилятор жалуется, что MyData
уже больше не соответствует протоколу. Во-вторых, нужно разбить это на два расширения и явно привязать TargetType.
extension MyData : Convertable {
typealias TargetType = Int
func convert() -> Int { return data }
}
extension MyData : Convertable {
typealias TargetType = String
func convert() -> String { return String(data) }
}
Это приводит к тому, что компилятор в настоящее время жалуется TargetType
была пересмотрена.
Моя последняя попытка была определить два протокола, которые расширяют протокол Convertable
и ограничить TargetType
, а затем реализовать их обоих с помощью расширения:
protocol ConvertableString : Convertable {
associatedtype TargetType = String
}
protocol ConvertableInt : Convertable {
associatedtype TargetType = Int
}
extension MyData : ConvertableInt {
func convert() -> Int { return self.data }
}
extension MyData : ConvertableString {
func convert() -> String { return String(self.data) }
}
который теперь делает компилятор счастливым для расширения, но уже не для вызов show
, потому что он не знает, что он может вызывать функцию с MyData
.
Есть ли что-то, что я наблюдал или это в настоящее время невозможно в быстром?
Это не только в настоящее время невозможно, но, по моему мнению, вряд ли это будет возможно. Вы объявили протокол с одним единственным ассоциированным типом. Как он может быть установлен на два разных типа в одном и том же типе ?! – werediver
Ну, это не тот же протокол, так как протокол является общим для TargetType, существует так много вариантов протокола, как для TargetType. Вся идея наличия типов, связанных с протоколами, заключается в том, что вы можете различать их связанный тип. Если вы посмотрите на C#, там можно реализовать тот же интерфейс с разными типами, связанными с общим параметром. – Kolja
Ну, это не C#, и вы не должны думать об этом так, как было бы, потому что это просто не работает. – werediver