1.什么时候可以使用inout参数呢
答案是,在使用内存地址的时候来传递给inout参数
那什么是inout参数呢?
准确的说:inout参数将一个值传递给函数,然后函数改变了这个值,并将原有的inout修饰的变量的值替换,最后在函数返回结果的时候,被传递出来
Swift中的常量的值不允许被修改,在一段代码中,定义了一个函数,函数中的参数默认都为常量,如下图所示
var value: Int = 1
func NumberChanged(num: Int) {
num = 2
print(num)
}
NumberChanged(num: value )
此时编译无法通过。这意味着我们无法修改函数参数的值,如果想要在函数销毁后一个可以修改的参数值 并且参数依然存在,我们需要使用inout关键字,也就是说,使用了inout关键字后,可以在函数体内部修改参数的值,并且函数调用完成后会保留
var value: Int = 1
func NumberChanged(num: inout Int) {
num = 2
print(num)
}
NumberChanged(num: &value )
此时编译将通过
2.使用inout关键字有需要注意的地方
- 在使用
inout关键字的函数时,在调用的时候得加上&符号 inout在作为参数传入的时候为变量,不能是常量或者是字面量inout参数不能有默认值,不是一个可变参数- 多个
inout参数在函数中不能传入同一个变量,将会导致最终的值也不能确定 inout的本质是地址的传递(引用传递)
3.inout参数的本质是存储属性,属性观察期和计算属性
class animal {
var age: Int = 15 // 存储属性
var side: Int = 0 { // 带属性观察器的存储属性
willSet {
print("willSetSide", newValue)
}
didSet {
print("didSetSide", oldValue, side)
}
}
var girth: Int { // 计算属性
set {
age = newValue/side
print("setGirth", newValue)
}
get {
print("getGirth")
return age * side
}
}
func show() {
print("width=\(age), side=\(age), girth=\(girth)")
}
}
都是通过地址传递
总结inout参数的传递过程:
- 在函数被调用的时候,使用了
inout关键字的参数被拷贝 - 在函数的执行中,被拷贝的参数值被修改
- 在函数返回结果的时候,被拷贝的值再赋值给原有的变量
inout的传递中,先进行地址传递,再进行值的传递,即Copy in Copy Out的做法