157,swift中inout的用法(面试点:inout可以修改属性的值,inout是放在参数类型前,冒号后,mutating 放在方法的前面修改属性值)

inout是 Swift 中的关键字,可以放置于参数类型前,冒号之后。使用 inout之后,函数体内部可以直接更改参数值,而且改变会保留。

func swap(resSct: inout ResolutionStruct) {
    withUnsafePointer(to: &resSct) { print("During calling: \($0)") }
    let temp = resSct.height
    resSct.height = resSct.width
    resSct.width = temp
}

var iPhone6ResoStruct = ResolutionStruct(height: 1334, width: 750)
print(iPhone6ResoStruct)
withUnsafePointer(to: &iPhone6ResoStruct) { print("Before calling: \($0)") }
swap(resSct: &iPhone6ResoStruct)
print(iPhone6ResoStruct)
withUnsafePointer(to: &iPhone6ResoStruct) { print("After calling: \($0)") }

小结:值类型变量作为参数传入函数,外界和函数参数的内存地址一致,函数内对参数的更改得到了保留。
需要注意的是:
1.使用 inout 关键字的函数,在调用时需要在该参数前加上 & 符号
2.inout 参数在传入时必须为变量,不能为常量或字面量(literal)
3.inout 参数不能有默认值,不能为可变参数
4.inout 参数不等同于函数返回值,是一种使参数的作用域超出函数体的方式
5.多个inout 参数不能同时传入同一个变量,因为拷入拷出的顺序不定,那么最终值也不能确定

struct Point {
    var x = 0.0
    var y = 0.0
}

struct Rectangle {
    var width = 0.0
    var height = 0.0
    var origin = Point()
    
    var center: Point {
        get {
            print("center GETTER call")
            return Point(x: origin.x + width / 2,
                         y: origin.y + height / 2)
        }
        
        set {
            print("center SETTER call")
            origin.x = newValue.x - width / 2
            origin.y = newValue.y - height / 2
        }
    }
    
    func reset(center: inout Point) {
        center.x = 0.0
        center.y = 0.0
    }
    
}

var rect = Rectangle(width: 100, height: 100, origin: Point(x: -100, y: -100))
print(rect.center)
rect.reset(center: &rect.center)
print(rect.center)

// center GETTER call
// Point(x: -50.0, y: -50.0)

// center GETTER call
// center SETTER call

// center GETTER call
// Point(x: 0.0, y: 0.0)

inout参数的传递过程:

  1. 当函数被调用时,参数值被拷贝
  2. 在函数体内,被拷贝的参数修改
  3. 函数返回时,被拷贝的参数值被赋值给原有的变量

你可能感兴趣的:(157,swift中inout的用法(面试点:inout可以修改属性的值,inout是放在参数类型前,冒号后,mutating 放在方法的前面修改属性值))