swift inout 参数是变量还是指针?
Posted
技术标签:
【中文标题】swift inout 参数是变量还是指针?【英文标题】:Is swift inout parameter a variable or a pointer? 【发布时间】:2016-11-12 21:15:04 【问题描述】:在下面的代码中使用 swift inout 参数感觉有点失落:
var shouldContinue: Bool = true
func doSomeWork1(shouldContinue: inout Bool)
while shouldContinue
// ERROR: the compiler wants: doSomeWork2(shouldContinue: &shouldContinue)
doSomeWork2(shouldContinue: shouldContinue)
func doSomeWork2(shouldContinue: inout Bool)
while shouldContinue
为什么编译器需要 doSomeWork2(shouldContinue: &shouldContinue)
而不是 the compiler wants: doSomeWork2(shouldContinue: shouldContinue)
? shouldContinue
不是已经是 doSomeWork1() 范围内的指针吗???
【问题讨论】:
【参考方案1】:作为指针只是 inout 参数优化过程的副作用。它们实际上使用 copy-in copy-out 行为以不同的方式工作。因此,在函数内部,该参数被视为常规变量,而不是指针。如果将它传递给另一个接受 inout 参数的函数,则必须将其标记为这样。
传入传出参数如下:
当函数被调用时,参数的值被复制。
在函数体中,副本被修改。
当函数返回时,副本的值被分配给原始参数。
这个 行为称为复制输入复制输出或按值调用结果。为了 例如,当计算属性或具有观察者的属性是 作为 in-out 参数传递,它的 getter 被称为 函数调用及其设置器作为函数返回的一部分被调用。
作为一种优化,当参数是存储在物理上的值时 内存中的地址,内部和内部使用相同的内存位置 在函数体之外。优化的行为称为 call by 参考;它满足复制的所有要求 复制出模型,同时消除复制的开销。编写你的代码 使用copy-in-copyout给出的模型,不依赖于 引用调用优化,以便它与 or 正确运行 没有优化。
In-Out Parameters
【讨论】:
感谢您的回复。如果我理解正确,复制入复制出行为意味着我不能使用我的 bool 变量来取消在其他线程上完成的工作?我的意思是如果我更改原始shouldContinue
的值,它不会在函数内部发生变化,但是从函数返回时会恢复旧值?
是的,你不能在线程之间使用它。您可以做的是使用布尔字段创建类,然后在多个线程中使用该类的实例。在这种情况下,您不需要 inout 参数。类实例是引用(指针),它将被传递,您将从多个线程读取和写入相同的布尔值..
有没有“更简单的方法”?创建一个持有布尔值的类似乎有点矫枉过正/混乱。
AFAIK 没有。唯一更简单的方法是直接读取全局布尔值。
IMO 使用类实例作为参数比使用全局布尔值更灵活、更好。【参考方案2】:
来自:Matt Neuburg 书籍“ios 13 Programming Fundamentals with Swift”。 :
如果我们想要一个函数改变传递给它的参数的原始值,我们必须执行以下操作:
我们要修改的参数类型必须声明为inout。 当我们调用函数时,保存要修改的值的变量必须用var声明,而不是let。 我们必须传递它的地址,而不是将变量作为参数传递。这是通过在其名称前加上与号 (&) 来完成的。我们的 removeCharacter(_:from:) 现在看起来像这样:
func removeCharacter(_ c:Character, from s: inout String) -> Int
var howMany = 0
while let ix = s.firstIndex(of:c)
s.remove(at:ix)
howMany += 1
return howMany
我们对 removeCharacter(_:from:) 的调用现在看起来像这样: var s = "你好" 让结果 = removeCharacter("l", from:&s) 调用后,结果为 2,s 为“heo”。当我们将其作为 from: 参数传递时,请注意名称 s 之前的与号。它是必需的;如果你省略它,编译器会阻止你。我喜欢这个要求,因为它迫使我们明确地向编译器和我们自己承认,我们即将做一些潜在危险的事情:作为副作用,我们让这个函数修改自身之外的值。
【讨论】:
以上是关于swift inout 参数是变量还是指针?的主要内容,如果未能解决你的问题,请参考以下文章