泛型函数
1 func swapTwoValues<T>( a: inout T, b: inout T) { 2 let temporaryA = a 3 a = b 4 b = temporaryA 5 } 6 7 8 var someInt = 3 9 var anotherInt = 107 10 11 swapTwoValues(a: &someInt, b: &anotherInt) 12 13 14 var someString = "hello" 15 var anotherString = "world" 16 swapTwoValues(a: &someString, b: &anotherString) 17 print("----->someString:(someString), anotherString:(anotherString)")
打印结果:
(lldb) po someInt
107
(lldb) po anotherInt
3
----->someString:world, anotherString:hello
命名类型参数
泛型数组
1 func makeArray<Item>(repeating item: Item , numberOfTimes: Int ) -> [Item] { 2 var result = [Item]() 3 for _ in 0..<numberOfTimes { 4 result.append(item) 5 } 6 return result 7 } 8 9 let test:[String] = self.makeArray(repeating: "无尽战刃", numberOfTimes: 4) 10 for item in test { 11 print("----->(item)") 12 } 13 14 //或者 15 let test1:Array<String> = self.makeArray(repeating: "无尽战刃", numberOfTimes: 4) 16 for item in test1 { 17 print("----->(item)") 18 }
打印结果:
----->无尽战刃
----->无尽战刃
----->无尽战刃
----->无尽战刃
泛型类型
泛型类型:通常在泛型函数中,Swift 允许你定义你自己的泛型类型。这些自定义类、结构体和枚举作用于任何类型,如同Array和Dictionary的用法。
1 struct Stack<T> { 2 var items = [T]() 3 mutating func push(item: T) { 4 items.append(item) 5 } 6 mutating func pop() -> T { 7 return items.removeLast() 8 } 9 } 10 11 12 13 var stackOfStrings = Stack<String>() 14 15 stackOfStrings.push(item: "uno") 16 stackOfStrings.push(item: "dos") 17 stackOfStrings.push(item: "tres") 18 stackOfStrings.push(item: "cuatro") 19 let fromTheTop = stackOfStrings.pop() 20 print("1.5---->fromTheTop:(fromTheTop)")
打印结果:
1.5---->fromTheTop:cuatro
扩展一个泛型类型
1 struct Stack<T> { 2 var items = [T]() 3 mutating func push(item: T) { 4 items.append(item) 5 } 6 mutating func pop() -> T { 7 return items.removeLast() 8 } 9 } 10 11 extension Stack { 12 var topItem: T? { 13 return items.isEmpty ? nil :items[items.count - 1] 14 } 15 16 } 17 18 19 var stackOfStrings = Stack<String>() 20 stackOfStrings.push(item: "uno") 21 stackOfStrings.push(item: "dos") 22 stackOfStrings.push(item: "tres") 23 stackOfStrings.push(item: "cuatro") 24 25 print("1.5---->fromTheTop:(stackOfStrings.topItem)")
打印结果:
1.5---->fromTheTop:Optional("cuatro")
类型约束
swapTwoValues函数和Stack类型可以作用于任何类型,不过,有的时候对使用在泛型函数和泛型类型上的类型强制约束为某种特定类型是非常有用的。类型约束指定了一个必须继承自指定类的类型参数,或者遵循一个特定的协议或协议构成。
类型约束语法
你可以写一个在一个类型参数名后面的类型约束,通过冒号分割,来作为类型参数链的一部分。这种作用于泛型函数的类型约束的基础语法如下所示(和泛型类型的语法相同)
1 func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { //第一个类型参数T,有一个需要T必须是SomeClass子类的类型约束;第二个类型参数U,有一个需要U必须遵循SomeProtocol协议的类型约束 2 // function body goes here 3 }
第一个类型参数T,有一个需要T必须是SomeClass子类的类型约束;第二个类型参数U,有一个需要U必须遵循SomeProtocol协议的类型约束。
类型约束行为
这里有个名为findStringIndex的非泛型函数,该函数功能是去查找包含一给定String值的数组。若查找到匹配的字符串,findStringIndex函数返回该字符串在数组中的索引值(Int),反之则返回nil。
1 func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? { //findIndex中这个单个类型参数写做:T: Equatable,也就意味着“任何T类型都遵循Equatable协议”。 2 for (index, value) in array.enumerated() { 3 if value == valueToFind { 4 return index 5 } 6 } 7 8 return nil 9 } 10 11 12 print("findIndex--->(String(describing: findIndex(array: ["Mike", "Malcolm", "Andrea"], valueToFind: "Andrea")))")
打印结果:
findIndex--->Optional(2)