Swift rodzajowych
Swift zapewnia ogólny elastyczny i pozwala na pisanie wielokrotnego funkcje i rodzaje.
Swift standardowa biblioteka jest zbudowany z kodem rodzajowy.
Swift tablice i słowniki są ogólne typy set.
Można utworzyć tablicę int, można utworzyć tablicę ciągów, a nawet tablicę danych może być dowolny rodzaj innego Swift.
Poniższy przykład jest non-generic wymiany funkcja wymiany dwóch wartości 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)")
Wyjście powyżej wykonywanie programu jest:
交换前数据: 100 和 200 交换后数据: 200 和 100
Funkcje generyczne mogą uzyskać dostęp do wszelkiego rodzaju, takich jak int lub String.
Poniższy przykład jest rodzajowy funkcja wymiany zamiany dwóch wartości int wyrażenie:
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)")
Wyjście powyżej wykonywanie programu jest:
交换前数据: 100 和 200 交换后数据: 200 和 100 交换前数据: A 和 B 交换后数据: B 和 A
Generic wersja tej funkcji za pomocą nazwy typu zastępczy (zazwyczaj reprezentowany przez literę T w tym przypadku) zamiast rzeczywistych nazw typów (takich jak int, string lub podwójne). Zastępczy nazwa typu nie może sugerować, jakiego typu T, ale sugeruje, A i B muszą być tego samego typu T, niezależnie od tego, jakiego typu T reprezentuje. Tylko wymiana (_: _ :) funkcji, gdy przeszedł do każdego typu połączeń w celu określenia rzeczywistego typu T reprezentuje.
Inną różnicą jest to, że ta ostatnia nazwa funkcji następuje nazwą rodzajową rodzaju zastępczego (t) jest w nawiasach kątowych (
Ogólny typ
Swift pozwala definiować własne typy generyczne.
Własne klasy, struktury i wyliczenia stosowane do każdego rodzaju jak Array i słownik użytkowania.
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()
Wyjście powyżej wykonywanie programu jest:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"]
Rozszerzony typ ogólny
Po przedłużeniu ogólny typ czasu (rozszerzenie za pomocą słów kluczowych), nie ma potrzeby, aby dostarczyć listę parametr typu w rozszerzonej definicji. Wygodniejsze jest prymitywne, że definicja typu parametru typ zadeklarowany w wykazie mogą być rozszerzane w użyciu i nazwy parametrów z oryginalnego typu zostaną wykorzystane jako punkt odniesienia do pierwotnej definicji parametru typu.
Przykłady
Poniższy przykład przedłuża ogólny typ TOS dodać tylko do odczytu o nazwie pierwsze obliczenie, zwróci Top elementów stosu i nie zostaną usunięte ze stosu.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)") }
Wyjście powyżej wykonywanie programu jest:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"] 栈顶部项:类型参数名
Rodzaj ograniczenia
Rodzaj ograniczenia określa, że parametr typu musi dziedziczyć z określonej klasy lub śledzić konkretny protokół lub kompozycję.
Składnia ograniczenie Rodzaj
Można napisać ograniczenie typu w tylnej części nazw parametrów typu, podzielonej przez jelita grubego, jako część łańcucha parametrów typu. Takie akty na podstawie rodzaju przymusu składni funkcji generycznych są następujące (tego samego rodzaju składni):
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // 这里是函数主体 }
Przykłady
// 函数可以作用于查找一字符串数组中的某个字符串 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)") }
Wyjście powyżej wykonywanie programu jest:
llama 的下标索引值为 2
Przykłady rodzaju stowarzyszenia
Swift typealias słowo kluczowe użyte do ustawiania rodzaju stowarzyszenia.
Określ protokół, czasami zadeklarować jedną lub więcej powiązanych rodzaj części protokołu definicji jest bardzo przydatna jako.
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)
Wyjście powyżej wykonywanie programu jest:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "参数类型"] ["Swift", "泛型", "参数类型", "类型参数名"]
W przypadku stwierdzenia
Rodzaj przymusu, aby zapewnić zgodność z definicji typu rodzajowego od ograniczeń funkcji lub klasy.
Można zdefiniować parametry rachunku gdzie ograniczenie na liście parametrów.
Gdzie można napisać oświadczenie, a następnie na liście parametrów typu z tyłu, gdzie jest instrukcja, a następnie przez jeden lub więcej rodzajów ograniczeń dla stowarzyszenia i (lub) równowartość jednego lub więcej typów i rodzajów stowarzyszeniu między (równość) relacji.
Przykłady
Poniższy przykład definiuje funkcję o nazwie rodzajowej allItemsMatch, używany w celu sprawdzenia, czy dwa przypadki pojemnik zawiera te same elementy w tej samej kolejności.
Jeśli wszystkie elementy można dopasować, a następnie powrót do wartości logicznej true, w przeciwnym razie false.
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 0pl<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)
Wyjście powyżej wykonywanie programu jest:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "Where 语句"] ["Swift", "泛型", "Where 语句"]