Swift:结构体、类与闭包
2021-07-06 本文已影响0人
码小菜
![](https://img.haomeiwen.com/i15969423/c487e230b754850c.png)
目录
一,结构体
二,类
三,闭包
一,结构体
1,介绍
-
Bool
、Int
、String
、Array
、Dictionary
等常见类型都是结构体 - 编译器会为结构体自动生成一个或多个初始化器,宗旨是保证所有成员都有初始值
- 如果自定义了初始化器,编译器就不会自动生成
- 在结构体内部定义的函数叫做方法
2,实例
![](https://img.haomeiwen.com/i15969423/a21da5976a8bfedc.png)
![](https://img.haomeiwen.com/i15969423/9ccac204fcedde0d.png)
![](https://img.haomeiwen.com/i15969423/88eead891995945a.png)
![](https://img.haomeiwen.com/i15969423/45e8ddb26cd1f908.png)
3,值类型
- 介绍
1>结构体是值类型
2>值类型在赋值或传参时,会产生深拷贝
3>在函数内部使用时,变量和成员都存储在栈空间
4>如果将值类型声明为常量,那么变量和成员都不能被修改
- 实例(查看内存的工具)
![](https://img.haomeiwen.com/i15969423/6a68702f8f9c76b2.png)
![](https://img.haomeiwen.com/i15969423/8907c0e33e38a627.png)
![](https://img.haomeiwen.com/i15969423/041f8f0c283af2cc.png)
4,内存
![](https://img.haomeiwen.com/i15969423/8802820490fa6b65.png)
二,类
1,介绍
- 在无初始值的情况下,编译器不会为类自动生成初始化器
- 在有初始值的情况下,编译器会为类自动生成一个无参的初始化器
- 成员的初始化是在初始化器中完成的
- 在类内部定义的函数叫做方法
2,实例
![](https://img.haomeiwen.com/i15969423/94c20b8a902eb727.png)
![](https://img.haomeiwen.com/i15969423/1a05981d1014e100.png)
![](https://img.haomeiwen.com/i15969423/738eaa6baa4d2ee6.png)
![](https://img.haomeiwen.com/i15969423/c3505c756272b4e8.png)
3,引用类型
- 介绍
1>类是引用类型
2>引用类型在赋值或传参时,会产生浅拷贝
3>在函数内部使用时,变量存储在栈空间,成员存储在堆空间
4>堆空间的前16个字节用来存储类型信息和引用计数
5>如果将引用类型声明为常量,那么变量不能被修改,而成员可以被修改
- 实例
![](https://img.haomeiwen.com/i15969423/4787afd276e48c1f.png)
![](https://img.haomeiwen.com/i15969423/d2f132e68880b0b1.png)
![](https://img.haomeiwen.com/i15969423/561db222c2ca88fa.png)
4,值类型和引用类型
- 实例
![](https://img.haomeiwen.com/i15969423/2f6fcfb0ffa329b8.png)
- 图解
![](https://img.haomeiwen.com/i15969423/72fb640dff530d54.png)
5,内存
![](https://img.haomeiwen.com/i15969423/8de2573d026985d6.png)
三,闭包
1,闭包表达式
- 格式
![](https://img.haomeiwen.com/i15969423/a722324f2d506cb9.png)
- 简写
![](https://img.haomeiwen.com/i15969423/1745c9ff1177b879.png)
2,尾随闭包
- 条件:闭包表达式作为函数的最后一个实参
- 格式:将闭包表达式写在圆括号的外面
![](https://img.haomeiwen.com/i15969423/e824488c318b87bf.png)
3,自动闭包
-
@autoclosure
并非只支持最后一个参数 -
@autoclosure
只支持() -> T
格式的参数 - 有无
@autoclosure
会构成函数重载
![](https://img.haomeiwen.com/i15969423/13ff91e7ef4df9a2.png)
4,变量捕获
- 实例
![](https://img.haomeiwen.com/i15969423/b7fa481d98d2af82.png)
- 为何捕获
number
存储在栈空间,当test
函数执行完就会销毁,但plus
函数还会用到它,所以就将number
捕获到堆空间,以延长它的寿命
- 底层操作
第19行代码
1>将plus
函数的地址存储到ps
变量的前8个字节中
2>申请一份堆空间:类型信息占8个字节、引用计数占8个字节、number
的值占8个字节
3>将堆空间的地址存储到ps
变量的后8个字节中
第20、21、22行代码
1>从ps
变量中取出plus
函数和堆空间的地址
2>调用plus
函数并将2、3、4和堆空间的地址作为参数传递进去
3>从堆空间中取出number
的值,与2、3、4相加之后再存储进去
- 汇编分析
第19行代码
![]()
![]()
第20行代码
![]()
![]()
![]()
![]()
5,闭包
- 一个函数和它捕获的局部常量/变量组合起来称为闭包
- 都是存储在堆空间,可以把闭包想象成类的实例对象
![](https://img.haomeiwen.com/i15969423/ccdd6483c3afe402.png)
6,捕获时机
![](https://img.haomeiwen.com/i15969423/137f8620696df925.png)