Swift Generik
Swift menyediakan fleksibel generik dan memungkinkan Anda untuk menulis fungsi dapat digunakan kembali dan jenis.
perpustakaan standar Swift dibangun oleh kode generik.
array Swift dan jenis kamus yang ditetapkan generik.
Anda dapat membuat sebuah array Int, Anda dapat membuat array String, atau bahkan data array dapat menjadi semua jenis Swift lainnya.
Contoh berikut adalah pertukaran fungsi non-generik untuk pertukaran dua nilai Int:
// 定义一个交换两个变量的函数 func exchange(inout a: Int, inout b: Int) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("交换前数据: \(numb1) 和 \(numb2)") exchange(&numb1, b: &numb2) print("交换后数据: \(numb1) 和 \(numb2)")
Output di atas eksekusi program adalah:
交换前数据: 100 和 200 交换后数据: 200 和 100
fungsi generik dapat mengakses semua jenis, seperti Int atau String.
Contoh berikut adalah fungsi generik untuk tukar menukar dua nilai Int dan String:
func exchange<T>(inout a: T, inout b: T) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("交换前数据: \(numb1) 和 \(numb2)") exchange(&numb1, b: &numb2) print("交换后数据: \(numb1) 和 \(numb2)") var str1 = "A" var str2 = "B" print("交换前数据: \(str1) 和 \(str2)") exchange(&str1, b: &str2) print("交换后数据: \(str1) 和 \(str2)")
Output di atas eksekusi program adalah:
交换前数据: 100 和 200 交换后数据: 200 和 100 交换前数据: A 和 B 交换后数据: B 和 A
versi generik dari fungsi ini menggunakan nama jenis placeholder (biasanya diwakili oleh huruf T dalam kasus ini) bukan nama jenis sebenarnya (seperti Int, String atau Double). Placeholder nama tipe tidak harus menunjukkan apa jenis T, tapi itu menunjukkan a dan b adalah tipe T yang sama harus, terlepas dari apa jenis T mewakili. Hanya exchange (_: _ :) fungsi ketika melewati di setiap jenis panggilan dalam rangka untuk menentukan jenis sebenarnya T mewakili.
Perbedaan lain adalah bahwa ini nama fungsi yang terakhir diikuti dengan nama generik dari jenis placeholder (T) tertutup dalam kurung sudut (
jenis generik
Swift memungkinkan Anda untuk menentukan jenis generik Anda sendiri.
kelas kustom, struktur, dan mantri diterapkan untuk semua jenis sebagai Array dan penggunaan kamus.
struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push("Swift") print(tos.items) tos.push("泛型") print(tos.items) tos.push("类型参数") print(tos.items) tos.push("类型参数名") print(tos.items) let deletetos = tos.pop()
Output di atas eksekusi program adalah:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"]
jenis generik diperpanjang
Ketika Anda memperpanjang jenis generik waktu (ekstensi menggunakan kata kunci), Anda tidak perlu menyediakan jenis daftar parameter dalam definisi diperpanjang. Lebih nyaman itu adalah bahwa definisi jenis jenis parameter primitif dinyatakan dalam daftar dapat diperluas digunakan dan nama-nama parameter dari jenis asli akan digunakan sebagai referensi untuk definisi asli dari jenis parameter.
contoh
Contoh berikut meluas jenis TOS generik, untuk menambahkan properti read-only bernama perhitungan pertama, itu akan mengembalikan atas saat elemen stack dan tidak akan dihapus dari stack.struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push("Swift") print(tos.items) tos.push("泛型") print(tos.items) tos.push("类型参数") print(tos.items) tos.push("类型参数名") print(tos.items) // 扩展泛型 TOS 类型 extension TOS { var first: T? { return items.isEmpty ? nil : items[items.count - 1] } } if let first = tos.first { print("栈顶部项:\(first)") }
Output di atas eksekusi program adalah:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"] 栈顶部项:类型参数名
Jenis kendala
Jenis kendala menetapkan bahwa parameter jenis harus mewarisi dari kelas tertentu atau mengikuti protokol atau komposisi tertentu.
sintaks kendala Jenis
Anda dapat menulis kendala ketik belakang jenis nama parameter, dibagi dengan titik dua, sebagai bagian dari rantai jenis parameter. tindakan tersebut atas dasar jenis sintaks kendala untuk fungsi generik adalah sebagai berikut (jenis generik yang sama sintaks):
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // 这里是函数主体 }
contoh
// 函数可以作用于查找一字符串数组中的某个字符串 func findStringIndex(array: [String], _ valueToFind: String) -> Int? { for (index, value) in array.enumerate() { if value == valueToFind { return index } } return nil } let strings = ["cat", "dog", "llama", "parakeet", "terrapin"] if let foundIndex = findStringIndex(strings, "llama") { print("llama 的下标索引值为 \(foundIndex)") }
Output di atas eksekusi program adalah:
llama 的下标索引值为 2
Contoh jenis asosiasi
typealias Swift kata kunci yang digunakan untuk mengatur jenis asosiasi.
Mendefinisikan protokol, kadang-kadang menyatakan satu atau jenis lainnya yang terkait protokol bagian dari definisi ini sangat berguna sebagai.
protocol Container { // 定义了一个ItemType关联类型 typealias ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } // 遵循Container协议的泛型TOS类型 struct TOS<T>: Container { // original Stack<T> implementation var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } // conformance to the Container protocol mutating func append(item: T) { self.push(item) } var count: Int { return items.count } subscript(i: Int) -> T { return items[i] } } var tos = TOS<String>() tos.push("Swift") print(tos.items) tos.push("泛型") print(tos.items) tos.push("参数类型") print(tos.items) tos.push("类型参数名") print(tos.items)
Output di atas eksekusi program adalah:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "参数类型"] ["Swift", "泛型", "参数类型", "类型参数名"]
dimana laporan
Jenis kendala untuk memastikan kepatuhan dengan definisi jenis fungsi generik kendala atau kelas.
Anda dapat menentukan parameter dari pernyataan di mana kendala dalam daftar parameter.
Di mana Anda dapat menulis sebuah pernyataan, diikuti oleh jenis daftar parameter di belakang, di mana pernyataan diikuti oleh satu atau lebih jenis kendala untuk asosiasi, dan (atau) setara dengan satu atau lebih jenis dan tipe hubungan antara hubungan (kesetaraan).
contoh
Contoh berikut mendefinisikan fungsi generik bernama allItemsMatch, digunakan untuk memeriksa apakah dua contoh dari Kontainer mengandung unsur-unsur yang sama dalam urutan yang sama.
Jika semua elemen bisa cocok, kemudian kembali ke nilai Boolean true, jika itu adalah palsu.
protocol Container { typealias ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } struct Stack<T>: Container { // original Stack<T> implementation var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } // conformance to the Container protocol mutating func append(item: T) { self.push(item) } var count: Int { return items.count } subscript(i: Int) -> T { return items[i] } } func allItemsMatch< C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, anotherContainer: C2) -> Bool { // 检查两个Container的元素个数是否相同 if someContainer.count != anotherContainer.count { return false } // 检查两个Container相应位置的元素彼此是否相等 for i in 0..<someContainer.count { if someContainer[i] != anotherContainer[i] { return false } } // 匹配所有项,返回 true return true } var tos = Stack<String>() tos.push("Swift") print(tos.items) tos.push("泛型") print(tos.items) tos.push("Where 语句") print(tos.items) var eos = ["Swift", "泛型", "Where 语句"] print(eos)
Output di atas eksekusi program adalah:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "Where 语句"] ["Swift", "泛型", "Where 语句"]