Swift的inout类型

1,459 阅读2分钟

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的做法