Swift 闭包捕获和 inout 变量

标签 swift

考虑以下代码:

func foo(inout success: Bool) -> (()->()) {
    return { _ in
        success = true
        print (success)
    }
}

var success = false
let closure = foo(&success)

closure()          //prints "true"
print(success)     //prints "false"

闭包似乎是创建成功的副本,并没有改变原来的。为什么会这样?我曾假设闭包会指向原始闭包,因为我们正在传递一个 inout 变量。

最佳答案

这不会更新您的 success 变量是有道理的,因为您的 inout 参数是 foo 的参数,而不是闭包的参数本身。如果将 inout 参数作为闭包的参数,您将获得所需的行为:

var success = false
let closure = { (inout flag: Bool) -> () in
    flag = true
    print(flag)
}

closure(&success)  //prints "true"
print(success)     //prints "true"

只要您将 inout 参数作为闭包的参数,此模式也适用于该函数:

func foo() -> ((inout Bool)->()) {
    return { flag in
        flag = true
        print (flag)
    }
}

var success = false
let closure = foo()

closure(&success)  //prints "true"
print(success)     //prints "true"

如果您使用引用类型,您还会获得所需的行为:

class BooleanClass: CustomStringConvertible {
    var value: Bool

    init(value: Bool) {
        self.value = value
    }

    var description: String { return "\(value)" }
}

func foo(flag: BooleanClass) -> (()->()) {
    return {
        flag.value = true
        print (flag)
    }
}

let success = BooleanClass(value: false)
let closure = foo(success)

closure()          //prints "true"
print(success)     //prints "true"

关于Swift 闭包捕获和 inout 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36851616/

相关文章:

ios - NavBar 按钮不会拖到 UIViewController 的右上角

swift - xcdatamodeld 我必须填写所有属性吗

swift - 从未使用过捕获 self

ios - 有没有更简单的方法将 XML 转换为 Plist?

快速错误: Consecutive declarations on a line must be separated by ';'

iOS:谷歌地图 API - markerInfoWindow 与 markerInfoContents

swift - DateString 到 timeStamp 用于在 Swift 中排序

ios - 已发送的消息在 JSQMessageViewController 中添加了两次

swift : Generic parameter 'T' could not be inferred

swift - 如何在线程实例上执行 block ?