Swift:19 泛型
泛型讓你能夠根據自定義的需求,編寫出適用于任意類型、靈活可重用的函數及類型。它能讓你避免代碼的重復,用一種清晰和抽象的方式來表達代碼的意圖。
泛型函數
泛型函數可以適用于任何類型,下面定義一個swapTwoValues(::) 函數可以用來交互任意兩個同類型的變量的值。
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
var one = 1,two = 2
swapTwoValues(&one, &two)
print("One=\(one),Two=\(two)")
//打?。篛ne=2,Two=1
var strOne = "One", strTwo = "Two"
swapTwoValues(&strOne, &strTwo)
print("One=\(strOne),Two=\(strTwo)")
//打?。篛ne=Two,Two=One
var doubleOne = 1.0,doubleTwo = 2.0
swapTwoValues(&doubleOne, &doubleTwo)
print("One=\(doubleOne),Two=\(doubleTwo)")
//打?。篛ne=2.0,Two=1.0
泛型類型
除了泛型函數,Swift還允許你定義泛型類型。這些自定義類、結構體和枚舉可以適用于任何類型,類似于 Array 和 Dictionary。下面示例代碼展示了使用結構體泛型實現棧集合類型。
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
func toString() {
for item in items {
print("\(item)",terminator:",")
}
}
}
var stack = Stack<String>()
stack.push("東")
stack.push("西")
stack.push("南")
stack.push("北")
stack.toString()
print()
stack.pop()
stack.toString()
print()
stack.pop()
stack.pop()
stack.toString()
代碼執行結果如下圖所示。
類型約束
有的時候如果能將使用在泛型函數和泛型類型中的類型添加一個特定的類型約束,將會是非常有用的。類型約束可以指定一個類型參數必須繼承自指定類,或者符合一個特定的協議或協議組合。類型約束語法如下。
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
// 這里是泛型函數的函數體部分
}
下面代碼演示在某個數組中查找某個元素的位置,如果數組中不存在該元素,則返回nil。
func findIndex<T: Equatable>(of valueToFind: T, in array:[T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
var arr = ["北京","上海","廣州","深圳"]
let pos = findIndex(of: "廣州", in: arr)
if let p = pos {
print("在位置\(p)找到元素'廣州'")
}else{
print("沒有找到元素'廣州'")
}
let pos1 = findIndex(of: "南京", in: arr)
if let p = pos1 {
print("在位置\(p)找到元素'南京'")
}else{
print("沒有找到元素'南京'")
}
代碼執行結果如下圖所示。
示例代碼
https://github.com/99ios/23.20