Capturing a struct reference in a closure doesn't allow mutations to occur

后端 未结 3 945
有刺的猬
有刺的猬 2021-01-14 11:14

I am trying to see if I can use structs for my model and was trying this. When I call vm.testClosure(), it does not change the value of x and I am

3条回答
  •  -上瘾入骨i
    2021-01-14 11:36

    An inout argument isn't a reference to a value type – it's simply a shadow copy of that value type, that is written back to the caller's value when the function returns.

    What's happening in your code is that your inout variable is escaping the lifetime of the function (by being captured in a closure that is then stored) – meaning that any changes to the inout variable after the function has returned will never be reflected outside that closure.

    Due to this common misconception about inout arguments, there has been a Swift Evolution proposal for only allowing inout arguments to be captured by @noescape closures. As of Swift 3, your current code will no longer compile.

    If you really need to be passing around references in your code – then you should be using reference types (make your Model a class). Although I suspect that you'll probably be able to refactor your logic to avoid passing around references in the first place (however without seeing your actual code, it's impossible to advise).

    (Edit: Since posting this answer, inout parameters can now be compiled as a pass-by-reference, which can be seen by looking at the SIL or IR emitted. However you are unable to treat them as such due to the fact that there's no guarantee whatsoever that the caller's value will remain valid after the function call.)

提交回复
热议问题