Mam protokół, mój kod szybkiego połączenia Mam protokół z powiązanym typem i dwie metody. Obie metody definiują różne ogólne ograniczenia dla skojarzonego typu protokołu. I chciałbym, aby struct był zgodny z protokołem, ale z dwoma różnymi powiązanymi typami.implementuj protokół z innym powiązanym typem:
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
}
Jako rozszerzenie robię struct zgodne z protokołem gdzie TargetType
będzie String
, aby przekazać je do metody pokazu:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
}
Jak dotąd wszystko działa zgodnie z oczekiwaniami. Ale teraz lubię mieć strukturę zgodną z protokołem Convertable
, gdy TargetType
jest związany z Int. Co wydaje się niemożliwe?
Pierwszą rzeczą próbowałem było dodać drugą definicję metody konwersji do rozszerzenia:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
func convert() -> Int { return data }
}
Kompilator teraz narzeka, że nie ma już MyData
zgodne z protokołem. Drugim było podzielenie tego na dwa rozszerzenia i bezpośrednie powiązanie TargetType.
extension MyData : Convertable {
typealias TargetType = Int
func convert() -> Int { return data }
}
extension MyData : Convertable {
typealias TargetType = String
func convert() -> String { return String(data) }
}
Ma to ten skutek, że kompilator teraz narzeka The TargetType
został na nowo.
Moja ostatnia próba była definiować dwa protokoły, które rozciągają się protokół Convertable
i ograniczyć TargetType
a następnie wdrożyć oboje poprzez rozszerzenie:
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) }
}
Co teraz robi kompilator szczęśliwy dla rozszerzeń, ale nie dłużej wywołanie show
, ponieważ nie wie, że może wywołać funkcję z MyData
.
Czy jest coś, co nadzorowałem, czy nie jest to obecnie możliwe w szybkim tempie?
Nie tylko obecnie nie jest to możliwe, ale moim zdaniem nie będzie to możliwe. Deklarowałeś protokół z _jednym typem powiązanym. Jak można ustawić dwa różne typy tego samego typu ?! – werediver
Cóż, to nie jest ten sam protokół, ponieważ protokół jest ogólny w stosunku do TargetType, istnieje tyle wariantów protokołu, co w przypadku TargetType. Cała idea posiadania typów powiązanych z protokołami polega na tym, że można je rozróżnić według skojarzonego typu. Jeśli spojrzysz na C#, istnieje możliwość zaimplementowania tego samego interfejsu z różnymi typami powiązanymi z ogólnym parametrem. – Kolja
Cóż, to nie jest C# i nie powinieneś myśleć o tym tak, jak by to było, ponieważ to po prostu nie działa. – werediver