Angenommen, ich habe diese Protokolle:
protocol SomeProtocol {
}
protocol SomeOtherProtocol {
}
Wenn ich nun eine Funktion möchte, die einen generischen Typ annimmt, aber diesem Typ entsprechen muss, kann SomeProtocol
ich Folgendes tun:
func someFunc<T: SomeProtocol>(arg: T) {
// do stuff
}
Aber gibt es eine Möglichkeit, eine Typbeschränkung für mehrere Protokolle hinzuzufügen?
func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {
}
Ähnliche Dinge verwenden Kommas, aber in diesem Fall würde die Deklaration eines anderen Typs gestartet. Folgendes habe ich versucht.
<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>
Antworten:
Sie können eine where-Klausel verwenden, mit der Sie beliebig viele Anforderungen angeben können (alle müssen erfüllt sein), die durch Kommas getrennt sind
Swift 2:
Swift 3 & 4:
oder die mächtigere where-Klausel:
Sie können natürlich die Protokollzusammensetzung (z. B.
protocol<SomeProtocol, SomeOtherProtocol>
) verwenden, diese ist jedoch etwas weniger flexibel.Mit
where
können Sie Fälle behandeln, in denen mehrere Typen beteiligt sind.Möglicherweise möchten Sie weiterhin Protokolle zur Wiederverwendung an mehreren Stellen erstellen oder dem zusammengestellten Protokoll nur einen aussagekräftigen Namen geben.
Swift 5:
Dies fühlt sich natürlicher an, da die Protokolle neben dem Argument stehen.
quelle
<T where T:SomeStruct, T:AnotherStruct>
? Für Klassen scheint der Compiler dies so zu interpretieren, dass er sagt "T ist eine Unterklasse von beiden", und für Strukturen beschwert er sich nur darüber"Type 'T' constrained to non-protocol type"
.where
Klausel weiterhin für zusätzliche Typ- / andere Verwendung verwenden, z. B.func someFunc<U, T: protocol<SomeProtocol, SomeOtherProtocol> where T.SubType == U>(arg: T, arg2: U) { ... }
für TypealienSubType
in zSomeProtocol
.Sie haben zwei Möglichkeiten:
Sie verwenden eine where-Klausel, wie in Jiaaros Antwort angegeben:
Sie verwenden einen Protokollzusammensetzungstyp :
quelle
typealias
. Vielen Dank!Die Entwicklung zu Swift 3.0 bringt einige Änderungen mit sich. Unsere beiden Möglichkeiten sehen jetzt etwas anders aus.
Verwenden einer
where
Klausel in Swift 3.0:Die
where
Klausel wurde jetzt an das Ende einer Funktionssignatur verschoben, um die Lesbarkeit zu verbessern. Die Vererbung mehrerer Protokolle sieht nun folgendermaßen aus:Verwenden des
protocol<>
Konstrukts in Swift 3.0:Die Zusammensetzung unter Verwendung des
protocol<>
Konstrukts ist veraltet. Das frühereprotocol<SomeProtocol, SomeOtherProtocol>
sieht jetzt so aus:Verweise.
Weitere Informationen zu den Änderungen für
where
finden Sie hier: https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.mdWeitere Informationen zu den Änderungen für das Protokoll <> -Konstrukt finden Sie hier: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
quelle
Swift 3 bietet bis zu 3 verschiedene Möglichkeiten, Ihre Funktion zu deklarieren.
1.
&
Operator verwenden2.
where
Klausel verwenden3.
where
Klausel und&
Operator verwendenBeachten Sie auch, dass Sie verwenden können
typealias
, um Ihre Funktionsdeklaration zu verkürzen.quelle