Katakanlah saya memiliki protokol ini:
protocol SomeProtocol {
}
protocol SomeOtherProtocol {
}
Sekarang, jika saya ingin fungsi yang menggunakan tipe generik, tetapi tipe itu harus sesuai dengan yang SomeProtocol
bisa saya lakukan:
func someFunc<T: SomeProtocol>(arg: T) {
// do stuff
}
Tetapi apakah ada cara untuk menambahkan batasan tipe untuk banyak protokol?
func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {
}
Hal serupa menggunakan koma, tetapi dalam kasus ini, ia akan memulai deklarasi dari tipe yang berbeda. Inilah yang saya coba.
<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>
Jawaban:
Anda dapat menggunakan klausa di mana yang memungkinkan Anda menentukan sebanyak mungkin persyaratan yang Anda inginkan (semuanya harus dipenuhi) dipisahkan dengan koma
Swift 2:
Swift 3 & 4:
atau klausa mana yang lebih kuat:
Anda tentu saja dapat menggunakan komposisi protokol (misalnya,
protocol<SomeProtocol, SomeOtherProtocol>
), tetapi sedikit kurang fleksibel.Menggunakan
where
memungkinkan Anda menangani kasus-kasus di mana banyak jenis terlibat.Anda mungkin masih ingin membuat protokol untuk digunakan kembali di banyak tempat, atau hanya untuk memberikan protokol yang lengkap nama yang bermakna.
Swift 5:
Ini terasa lebih alami karena protokol di sebelah argumen.
sumber
<T where T:SomeStruct, T:AnotherStruct>
? Untuk kelas kompiler tampaknya menafsirkan ini dengan mengatakan "T adalah subkelas dari keduanya", dan untuk struct hanya mengeluh itu"Type 'T' constrained to non-protocol type"
.where
klausa untuk tipe tambahan / penggunaan lainnya, misalnyafunc someFunc<U, T: protocol<SomeProtocol, SomeOtherProtocol> where T.SubType == U>(arg: T, arg2: U) { ... }
untuk typealiasSubType
di misalnyaSomeProtocol
.Anda memiliki dua kemungkinan:
Anda menggunakan klausa tempat seperti yang ditunjukkan dalam jawaban Jiaaro:
Anda menggunakan jenis komposisi protokol :
sumber
typealias
. Terima kasih!Evolusi ke Swift 3.0 membawa beberapa perubahan. Dua pilihan kami sekarang terlihat sedikit berbeda.
Menggunakan
where
klausa di Swift 3.0:The
where
klausul sekarang pindah ke akhir tanda tangan fungsi untuk meningkatkan keterbacaan. Jadi beberapa protokol warisan sekarang terlihat seperti ini:Menggunakan
protocol<>
konstruk di Swift 3.0:Komposisi menggunakan
protocol<>
konstruk tidak lagi digunakan. Sebelumnyaprotocol<SomeProtocol, SomeOtherProtocol>
sekarang terlihat seperti ini:Referensi.
Info lebih lanjut tentang perubahan
where
ada di sini: https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.mdDan, lebih lanjut tentang perubahan protokol <> konstruk ada di sini: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
sumber
Swift 3 menawarkan hingga 3 cara berbeda untuk mendeklarasikan fungsi Anda.
1. Menggunakan
&
operator2. Menggunakan
where
klausa3. Menggunakan
where
klausa dan&
operatorPerhatikan juga bahwa Anda dapat menggunakan
typealias
untuk mempersingkat deklarasi fungsi Anda.sumber