泛型可以将类型参数话,提高代码的复用率,减少代码量
泛型的简单使用
假设我们要对两个值进行交换,我们需要写这么多方法
func swapValues(_ a: inout Int,_ b: inout Int) {
(a,b) = (b,a)
}
func swapValues(_ a: inout Double,_ b: inout Double) {
(a,b) = (b,a)
}
func swapValues(_ a: inout String,_ b: inout String) {
(a,b) = (b,a)
}
如果我们使用泛型的话
func swapValues(_ a: inout T,_ b: inout T) {
(a,b) = (b,a)
}
调用这一个方法就可以实现了各种类型的交换
泛型的本质
我们想一下泛型的本质是什么呢
- 1、根据传入值的不同,生成不同的函数。如果传入的是
int
类型就生成int
类型函数 - 2、没有生成新的函数
为了证实这个猜测,我们可以根据汇编查看一下是否生成了新的函数
func swapValues<T>(_ a: inout T,_ b: inout T) {
(a,b) = (b,a)
}
var a = 10
var b = 11
swap(&a, &b)
var c = "123"
var d = "456"
swap(&c, &d)
我们打断点看一下
0x1000008fe <+126>: callq 0x100000e66 ; symbol stub for: Swift.swap<A>(inout A, inout A) -> ()
0x1000009bf <+319>: callq 0x100000e66 ; symbol stub for: Swift.swap<A>(inout A, inout A) -> ()
我们可以发现两个函数地址是相同的,所以并没有生成新的函数。
关联类型(Associated Type)
关联类型的作用:给协议中用到的类型定义一个占位名称
协议中可以拥有多个关联类型
protocol Stackable {
associatedtype Element //关联类型
associatedtype Element1 //关联类型
mutating func push(_ element:Element)
mutating func pop() -> Element
func top() -> Element
}
类型约束
protocol Runnable {}
class Person {}
func swapValue<T:Person & Runnable>(_ a:inout T,_ b: inout T) {
(a,b) = (b,a)
}
参数是Person类型,又要遵守Runnable协议
不透明类型some
-
some
限制只能返回一种类型 -
some
除了作用在返回值类型上,一般还可以作用在属性类型上
可选项的本质
可选项的本质就是enum
类型
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
public init(_ some: Wrapped)
}
可选类型的实现就是枚举的判断
var age:Int? = 10
var age1:Optional<Int> = Optional<Int>.some(10)
var age2:Optional = .some(10)
age2 = nil
age2 = .none
func test(_ age:Int?) {
switch age {
case let v?:
print(v)
case nil:
print("none")
}
}
网友评论