Swift引用传递参数inout
Swift引用传递参数inout

Swift引用传递参数inout

inout 是 Swift 的一种参数修饰符,用于标记通过引用传递的参数。这意味着当将某个变量作为 inout 参数传递给函数时,该函数可以直接修改原始变量的值,而不仅仅是操作其副本。

特点

1、传递引用:inout 参数是通过变量的引用传递的,而不是值的副本。

2、变量会被修改:函数内部对 inout 参数的任何更改都会影响传入的原始变量。

3、使用 & 引用传递:调用函数时,需要在参数前加 & 符号,明确表示愿意让函数修改该变量。

语法

定义一个接受 inout 参数的函数:

func modifyValue(_ number: inout Int) {
    number += 10
}

调用函数时:

var myNumber = 5
modifyValue(&myNumber) // 使用 & 表示引用传递
print(myNumber) // 输出: 15

在这个例子中:

myNumber 的初始值是 5。

modifyValue 函数接收 myNumber 的引用并在内部修改它。

调用后,myNumber 的值被修改为 15。

使用场景

1、模拟引用传递

在 Swift 中,函数参数默认是按值传递的。使用 inout 可以让函数直接操作传入的变量。

func swapValues(_ a: inout Int, _ b: inout Int) {
    let temp = a
    a = b
    b = temp
}

var x = 3
var y = 7
swapValues(&x, &y)
print(x, y) // 输出: 7, 3

2、与 Objective-C 交互

在处理桥接的 Objective-C 方法(如 NSError ** 参数)时,inout 提供类似的行为。

注意事项

1、不能使用常量或字面量:inout 参数必须是可变的变量,不能是常量或字面量。

var value = 10
modifyValue(&value) // 正确
modifyValue(&10)    // 错误:字面量不能作为 inout 参数

2、函数内部可以为参数重新赋值为新实例:inout 参数的引用地址可以在函数内改变,但其内容可以改变。

func reset(_ number: inout Int) {
    number = 0 // 正确:修改内容
}

func invalidChange(_ number: inout Int) {
    let anotherNumber = 20
    number = anotherNumber //  合法地修改引用本身

}

3、避免不必要的使用:大多数情况下可以通过返回值来实现相同功能,只有在需要修改原始变量时才使用 inout。

inout 与 Objective-C 的桥接

在与 Objective-C 交互时,inout 是处理 NSError ** 的关键:

var error: NSError?
someObjectiveCFunction(&error) // 使用 & 传递引用

在这个例子中,Swift 的 &error 相当于将 NSError * 的地址传递给 Objective-C 方法,使其能够修改原始的 error 对象。

更深层次的理解:Swift 中的引用绑定

Swift 的 inout 参数是一种优化过的引用传递模式。传递变量时,Swift 会在函数内部操作一个引用,也允许改变它的指向。

理解引用和内容

对于引用类型(例如类实例),修改 inout 参数的属性是合法的,也可以重新赋值为一个新的对象。

修改内容

class Person {
    var name: String
    init(name: String) {
        self.name = name
    }
}

func changeName(_ person: inout Person) {
    person.name = "Alice" // 修改引用指向对象的内容
}

var user = Person(name: "Bob")
changeName(&user)
print(user.name) // 输出: Alice

示意流程图

改变引用

func reassignPerson(_ person: inout Person) {
    let user2 = Person(name: "Alice") // 允许改变引用
    person = user2
}

进一步验证

因为修改后的user和user2地址相同,当修改user2的name时,user1也跟随改变。

总结

inout 参数允许函数直接修改传入的变量值。

在 Swift 中,它可以用来实现类似 C 和 Objective-C 中的引用传递。

调用时,需使用 & 明确传递变量的引用。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注