Swift中的结构体
Swift
中的结构体
是通过struct
声明的
- 结构体的初始化
struct YYTeacher {
var age : Int
var name : String
}
对比下面这段class
的代码:
class YYTeacher {
var age : Int
var name : String
}
在代码编译
过程中,class
这段代码会报错:"Class 'YYTeacher' has no initializers"
。这是因为Swift
编译器在结构体
中自动
帮助我们合成
了初始化
方法,而class
中需要我们自己定义
带有参数的初始化
方法。意味着可以这样调用:
这一点也可以通过SIL
来查看:
上面是第一种情况:默认初始化没值也没有自定义带参初始化,则编译器自动生成带参初始化。
第二种情况:如果默认
初始化有值
第三种情况:如果自己定义
了带参初始化
方法
- 结构体是值类型
值类型
-
值类型
的地址
里面存储的就是值
- 传递过程中相当于
copy
一个副本
(深拷贝
)
通过lldb
查看:
通过SIL
里面也可以看出:
在main
中也只是调用了init
方法:
在init
中也是直接获取地址
进行赋值
,不参与任何的alloc
堆区内存分配`.
引用类型
-
引用类型
的地址
存储的是一个地址
- 传递过程中相当于
编辑
一个在线表格
,共享
状态(浅拷贝
)
下面例子是main.swift
中的一个class
:
class YYTeacher {
var age : Int = 12
}
var t = YYTeacher()
-
po t
: 打印的是t里面存储的东西(值类型则为值,引用类型则为地址)
。如果是引用类型,存储的地址则是通过malloc
对象在堆区
的地址 -
po withUnsafePointer(to: &t){print($0)}
:打印的是t自身的地址
,t自身在哪里就是哪里的地址
3、值类型和引用类型的区别:就像一个是在线表格
,一个是本地的excel
,当共享编辑一个在线表格
时就相当于一个引用类型
;而当通过QQ传一个excel
时就相当于一个值类型
,不共享状态。
注意:尽可能避免值类型中包含引用类型;虽然放在值类型中,在传递过程中不管是传递还是赋值的操作,对于当前的引用类型还是采用引用计数来管理的
。
Mutating
mutating
只用于值类型
中的方法
struct YYStack {
var items = [Int]()
// _ : 外部参数,可省略
//item : 内部参数,默认let不可变
func push(_ item : Int) {
print(item)
}
}
在上面这个例子
中,如果想要在push
方法里面修改items
或者item
,都是编译不通过
的。我们可以通过SIL
来看一下其中的原因
:
值类型self
里面存储的就是items
,要修改items就是要修改self.
这时要想修改items
,就需要在func
前面添加关键字mutating
.即:
struct YYStack {
var items = [Int]()
mutating func push(_ item : Int) {
items.append(item)
}
}
接下来可以通过SIL
看一下mutating
到底做了什么
:
可以看出:mutating
本质上就是给当前值类型添加了一个inout
关键字;而inout
的本质则是传递过程中传递
的是地址
(引用
)
inout
--> 输入输出参数
:修饰的是参数类型
,所以也可以修饰当前结构体
。