swift inout参数是变量还是指针?

时间:2016-11-12 21:15:05

标签: swift inout

我觉得在以下代码中使用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()范围内的指针???

2 个答案:

答案 0 :(得分:7)

作为指针只是inout参数的优化过程的副作用。它们实际上使用 copy-in copy-out 行为以不同的方式工作。所以内部函数将参数视为常规变量,而不是指针。如果将它传递给另一个带有inout参数的函数,则必须将其标记为。

  

输入输出参数传递如下:

     

调用该函数时,将复制参数的值。

     

在函数体中,修改了副本。

     

当函数返回时,副本的值将分配给原始参数。

     

此   行为称为copy-in copy-out或按值调用结果。对于   例如,当计算属性或具有观察者的属性是   作为in-out参数传递,其getter作为一部分被调用   函数调用及其setter作为函数return的一部分被调用。

     

作为优化,当参数是存储在物理上的值时   在内存中的地址,内部和内部都使用相同的内存位置   功能体外。优化的行为称为call by   参考;它满足了复制的所有要求   复制模型,同时消除了复制的开销。写下你的代码   使用copy-in copy-out给出的模型,而不依赖于   逐个引用的优化,以便它使用或正确运行   没有优化。

In-Out Parameters

答案 1 :(得分:0)

来自:Matt Neuburg书“ iOS 13使用Swift编程基础知识”:

如果我们希望函数更改传递给它的参数的原始值,则必须执行以下操作:

  • 我们要修改的参数类型必须声明为 inout
  • 当我们调用函数时,保存要修改的值的变量必须使用var声明,而不是让它声明。
  • 我们必须传递其地址,而不是将变量作为传递给参数。这是通过在其名称前加上与号(&)来完成的。

我们的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之前的与号。它是必需的;如果您省略它,编译器将阻止您。我喜欢这个要求,因为它迫使我们明确地向编译器以及对我们自己承认,我们将要做潜在的危险:作为副作用,我们让此函数修改自身之外的值。