在swift底层探索 03 - 值类型、引用类型中知道
值类型
在内存中直接保存具体的值,所以说值类型内部的值只能覆盖并不能修改
。
下面看2种情况

-
引用类型
即使被修饰为let
,依旧可以修改age
。因为:不可变的是a本身的地址指针,而a.age是被var修饰可以修改的

-
值类型
中就行不通了,因为age也保存在a的内存布局
中,而a的整块内存布局
是不允许修改的。需要用var
修饰才可以修改整块内存布局
。这一点值类型
就比较特殊。
1. mutating

- 这种情况下想要修改一下self内部的值,就难办了。因为
引用类型
可以修改self中的其他变量,而值类型
不可以。而这种需求是一定存在的。

解决---根据编译器提示

- 在方法前加一个
mutating
,可是这样做编译器到底做了什么?还是使用sil
来查看。sil如何获取和使用
sil文件

- 本质就是在方法第一个默认参数
self
前加上了inout,使self的修饰符从let变为var可修改
,从而达到修改的目的.
【总结】
- 因为方法的一个参数
self
是默认编译器自带的,我们是没法进行修饰的.利用mutating + func a()
语句使编译器将第一个默认参数self
改为var
mutating修饰方法,而inout 修饰参数
2. inout
我们都知道方法的参数默认都是let
不可变的,有时需要在方法体内对传入参数做修改.
比如像这样,编译器一定会报错的:

解决---模仿mutating的处理

- 解决方法就是在
参数类型前加上inout
,并且实现了不可变-值类型
的交换。
sil文件

- 有了
mutating
的过渡这部分就很好理解了吧~
【总结】
- inout相当于取地址,可以理解为地址传递,即引用
mutating修饰方法,而inout 修饰参数
网友评论