我觉得在以下代码中使用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)
? isn&#t; t shouldContinue
已经是doSomeWork1()范围内的指针???
答案 0 :(得分:7)
作为指针只是inout参数的优化过程的副作用。它们实际上使用 copy-in copy-out 行为以不同的方式工作。所以内部函数将参数视为常规变量,而不是指针。如果将它传递给另一个带有inout参数的函数,则必须将其标记为。
输入输出参数传递如下:
调用该函数时,将复制参数的值。
在函数体中,修改了副本。
当函数返回时,副本的值将分配给原始参数。
此 行为称为copy-in copy-out或按值调用结果。对于 例如,当计算属性或具有观察者的属性是 作为in-out参数传递,其getter作为一部分被调用 函数调用及其setter作为函数return的一部分被调用。
作为优化,当参数是存储在物理上的值时 在内存中的地址,内部和内部都使用相同的内存位置 功能体外。优化的行为称为call by 参考;它满足了复制的所有要求 复制模型,同时消除了复制的开销。写下你的代码 使用copy-in copy-out给出的模型,而不依赖于 逐个引用的优化,以便它使用或正确运行 没有优化。
答案 1 :(得分:0)
来自:Matt Neuburg书“ iOS 13使用Swift编程基础知识”:
如果我们希望函数更改传递给它的参数的原始值,则必须执行以下操作:
我们的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”,来自:&s) 通话后,结果为2,而s为“ heo”。当我们将其作为from:参数传递时,请注意名称s之前的与号。它是必需的;如果您省略它,编译器将阻止您。我喜欢这个要求,因为它迫使我们明确地向编译器以及对我们自己承认,我们将要做潜在的危险:作为副作用,我们让此函数修改自身之外的值。