Swift(二十三、泛型)
1、Swift入门学习笔记(第一版),对Swift的基础知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~ 2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。 二十三、泛型根据需求定义、适用任何类型的、灵活且可重用的函数和类型。避免重复代码。 泛型代码贯穿整个 1、泛型函数1.1、交换两个值实例例如交换两个 func swapTwoInts(inout a:Int,inout _ b:Int) {
let temporary = a
a = b
b = temporary
}
var oneInt = 2
var theOtherInt = 18
print("BeforeSwap -> oneInt:(oneInt),theOtherInt:(theOtherInt)")
swapTwoInts(&oneInt,&theOtherInt)
print("AfterSwap -> oneInt:(oneInt),theOtherInt:(theOtherInt)")
Output: BeforeSwap -> oneInt:2,theOtherInt:18
AfterSwap -> oneInt:18,theOtherInt:2
但是有时候我们要交换两个 因此可以利用泛型函数,可灵活的应用于任何类型 func swapTwoValues<T>(inout a:T,inout _ b:T) {
let temporary = a
a = b
b = temporary
}
var oneString = "oneString"
var theOtherString = "theOtherString"
print("BeforeSwap -> oneString:(oneString),theOtherString:(theOtherString)")
swapTwoValues(&oneString,&theOtherString)
print("AfterSwap -> oneString:(oneString),theOtherString:(theOtherString)")
Output: BeforeSwap -> oneString:oneString,theOtherString:theOtherString
AfterSwap -> oneString:theOtherString,theOtherString:oneString
1.2、语法说明func swapTwoValues<T>(inout a:T,inout _ b:T)
使用了占位类型名字(通常用字母 占位类型要用尖括号括起来 占位类型名字可以是任何有效的标识符 注意:swap函数,swift标准库本来就有自带的。功能与上面的函数相同 swap(&oneString,&theOtherString) print("SwapAgain -> oneString:(oneString),theOtherString:(theOtherString)")
Output: SwapAgain -> oneString:oneString,theOtherString:theOtherString
2、泛型类型创建一个泛型集类型:栈- struct Stack<T> {
var items = [T]()
mutating func push(item:T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
注意:定义的时候要制定所属类型 var stackOfStrings = Stack<String>()
stackOfStrings.push("A")
stackOfStrings.push("B")
stackOfStrings.push("C")
stackOfStrings.push("D")
print(stackOfStrings.items)
let fromTheTop = stackOfStrings.pop()
print(fromTheTop)
Output: ["A","B","C","D"]
D
3、扩展一个泛型类型泛型的扩展中可以使用原始类型的参数 扩展 extension Stack {
var topItem:T? {
return items.isEmpty ? nil : items[items.count-1]
}
}
let topItem = stackOfStrings.topItem
print(topItem!)
Output: C
4、类型约束有时候使用泛型类型或者泛型函数上的类型需要强制约定为某种特定类型,譬如必须继承自某指定类的类型参数,或遵循一个特定的协议或协议构成 例如 4.1、类型约束语法func someFunction<T: SomeClass,U: SomeProtocol>(someT: T,someU: U) {
// 这里是函数主体
}
Equatable协议官方文档提到了一个 5、关联类型定义协议时,声明一个或多个关联类型作为协议定义的一部分。 简单地说就是:类型的一个占位符,等到具体实现协议的时候才知道它具体是什么类型 定义一个容器协议,包含一个 protocol Container {
typealias ItemType
mutating func append(item:ItemType)
var count:Int{ get }
}
//遵循Container协议的泛型Stack类型
struct Stack<T>:Container {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
//Swift会自动推断出被用作关联类型ItemType类型是T,不用显式地写出.
//但是你写出来也没事 typealias ItemType = T
mutating func append(item: T) {
self.push(item)
}
var count:Int {
return items.count
}
}
var stackOfStrings = Stack<String>()
stackOfStrings.push("A")
stackOfStrings.push("B")
stackOfStrings.push("C")
stackOfStrings.push("D")
print(stackOfStrings.items)
let fromTheTop = stackOfStrings.pop()
print(fromTheTop,stackOfStrings.count)
Output: ["A","D"]
D 3
6、扩展一个存在的类型为一指定关联类型之前又讲到,一个类都实现了协议的内容,但是还没遵循,可以通过空扩展来实现遵循 这里也一样,比如 extension Array:Container { }
定义此扩展后,可以将任何Array当做Container使用 7、Where语句补充定义参数的约束。例如让一个关联类型遵循某个特定的协议,或特定的类型参数与关联类型相同 也可以写一个针对一个或多个关联参数的约束,以及一个或多个类型和关联类型间的等价关系 func allItemsMath<C1:Container,C2:Container where C1.ItemType == C2.ItemType,C1.ItemType:Equatable>(someContainer:C1,anotherContainer:C2) {
//函数内容
}
上述约束描述: OC不支持泛型(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |