在Swift和inout参数中通过闭包的变量捕获 [英] Variable capture by closures in Swift and inout parameters

查看:301
本文介绍了在Swift和inout参数中通过闭包的变量捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到当一个变量被Swift中的闭包捕获时,闭包实际上可以修改该值。这对我来说似乎很疯狂,是一种获得可怕的错误的好方法,特别是当同一个var被多个闭包捕获时。

I noticed that when a variable is captured by a closure in Swift, the closure can actually modify the value. This seems crazy to me and an excellent way of getting horrendous bugs, specially when the same var is captured by several closures.

var capture = "Hello captured"
func g(){
    // this shouldn't be possible!
    capture = capture + "!"
}

g()
capture

另一方面,有inout参数,它允许一个函数或闭包修改其参数。

On the other hand, there's the inout parameters, which allow a function or closure to modify its parameters.

对inout的需要是什么,即使捕获的变量已经可以修改有罪不罚

What's the need for inout, even captured variables can already be modified with impunity??!!

只是想了解这个背后的设计决策...

Just trying to understand the design decisions behind this...

推荐答案

大卫的答案是完全正确的,但我想我会给一个例子如何捕获实际上工作:

David's answer is totally correct, but I thought I'd give an example how capture actually works as well:

func captureMe() -> (String) -> () {

    //  v~~~ This will get 'captured' by the closure that is returned:
    var capturedString = "captured"

    return {

        // The closure that is returned will print the old value,
        // assign a new value to 'capturedString', and then 
        // print the new value as well:

        println("Old value: \(capturedString)")
        capturedString = $0
        println("New value: \(capturedString)")
    }
}

let test1 = captureMe()      // Output: Old value: captured
println(test1("altered"))    //         New value: altered

// But each new time that 'captureMe()' is called, a new instance
// of 'capturedString' is created with the same initial value:

let test2 = captureMe()               // Output: Old value: captured
println(test2("altered again..."))    //         New value: altered again...

// Old value will always start out as "captured" for every 
// new function that captureMe() returns. 

这样做的结果是,你不必担心关闭改变捕获的值 - 是的,它可以改变它,但只是对于返回的闭包的特定实例。返回的闭包的所有其他实例将获得他们自己的捕获值的独立副本,可以更改。

The upshot of that is that you don't have to worry about the closure altering the captured value - yes, it can alter it, but only for that particular instance of the returned closure. All other instances of the returned closure will get their own, independent copy of the captured value that they, and only they, can alter.

这篇关于在Swift和inout参数中通过闭包的变量捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆