Powiedzmy, że mam te protokoły:
protocol SomeProtocol {
}
protocol SomeOtherProtocol {
}
Teraz, jeśli chcę funkcję, która przyjmuje typ ogólny, ale ten typ musi być zgodny z, SomeProtocol
mogę zrobić:
func someFunc<T: SomeProtocol>(arg: T) {
// do stuff
}
Ale czy istnieje sposób na dodanie ograniczenia typu dla wielu protokołów?
func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {
}
Podobne rzeczy używają przecinków, ale w tym przypadku rozpoczęłoby to deklarację innego typu. Oto, czego próbowałem.
<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>
Odpowiedzi:
Możesz użyć klauzuli where, która pozwala określić dowolną liczbę wymagań (z których wszystkie muszą być spełnione) oddzielonych przecinkami
Swift 2:
Swift 3 i 4:
lub mocniejsza klauzula where:
Możesz oczywiście użyć kompozycji protokołu (np.
protocol<SomeProtocol, SomeOtherProtocol>
), Ale jest to trochę mniej elastyczne.Używanie
where
pozwala radzić sobie z przypadkami, w których zaangażowanych jest wiele typów.Nadal możesz tworzyć protokoły do ponownego wykorzystania w wielu miejscach lub po prostu nadać złożonemu protokołowi znaczącą nazwę.
Swift 5:
Wydaje się to bardziej naturalne, ponieważ protokoły są obok argumentu.
źródło
<T where T:SomeStruct, T:AnotherStruct>
? W przypadku klas kompilator wydaje się interpretować to jako stwierdzenie, że „T jest podklasą obu”, aw przypadku struktur po prostu narzeka"Type 'T' constrained to non-protocol type"
.where
klauzuli dla dodatkowego typu / innego użycia, np.func someFunc<U, T: protocol<SomeProtocol, SomeOtherProtocol> where T.SubType == U>(arg: T, arg2: U) { ... }
Dla aliasów typuSubType
w npSomeProtocol
.Masz dwie możliwości:
Używasz klauzuli gdzie wskazano w odpowiedzi Jiaaro:
Używasz typu kompozycji protokołu :
źródło
typealias
. Dzięki!Ewolucja do Swift 3.0 przynosi pewne zmiany. Nasze dwie opcje wyglądają teraz trochę inaczej.
Korzystanie z
where
klauzuli w Swift 3.0:where
Klauzula teraz przeniósł się do końca podpisu funkcji w celu poprawienia czytelności. Tak więc dziedziczenie wielu protokołów wygląda teraz następująco:Korzystanie z
protocol<>
konstrukcji w Swift 3.0:Kompozycja korzystająca z
protocol<>
konstrukcji jest przestarzała. Wcześniejprotocol<SomeProtocol, SomeOtherProtocol>
wygląda teraz tak:Bibliografia.
Więcej informacji na temat zmian dla
where
jest tutaj: https://github.com/apple/swift-evolution/blob/master/proposity/0081-move-where-expression.mdWięcej informacji na temat zmian w konstrukcji protokołu <> można znaleźć tutaj: https://github.com/apple/swift-evolution/blob/master/propeals/0095-any-as-existential.md
źródło
Swift 3 oferuje do 3 różnych sposobów deklarowania swojej funkcji.
1. Korzystanie z
&
operatora2. Korzystanie z
where
klauzuli3. Stosowanie
where
klauzuli i&
operatoraZauważ również, że możesz użyć
typealias
, aby skrócić deklarację funkcji.źródło