Swift 如何从转义闭包中更改inout参数?
我试图在转义闭包中修改函数的参数,如下所示:Swift 如何从转义闭包中更改inout参数?,swift,closures,Swift,Closures,我试图在转义闭包中修改函数的参数,如下所示: var completion = [()->Void]() func addCompletion(closure: @escaping ()->Void) { completion.append(closure) } func testAdd(v: inout Int) { addCompletion{ v = 1 // Compiler tells 'Escaping closure capture
var completion = [()->Void]()
func addCompletion(closure: @escaping ()->Void) {
completion.append(closure)
}
func testAdd(v: inout Int) {
addCompletion{
v = 1 // Compiler tells 'Escaping closure captures 'inout' parameter 'v'
print("hello1 \(v)")
}
}
var x = 0
testAdd(v:&x)
for comp in completion {
comp()
}
我想知道除了将其作为类对象转换为引用类型之外,是否还有其他方法可以让转义闭包更改周围变量(作为函数的inout参数)。
inout
被指定为具有“copy-in-copy-out”行为。调用函数时,会复制x
的值。在函数体中,可以修改x
的副本或其他内容。然后,当函数返回时,将再次复制副本,并将其分配给原始x
。“参考电话”可以作为一种优化
这解释了为什么不能在转义闭包中修改inout
参数。swift编译器不可能知道每个转义闭包何时返回,从而将修改后的值复制回来
您可以使用实际指针:
func testAdd(v: UnsafeMutablePointer<Int>) {
addCompletion{
v.pointee = 1 // you just need to change all references to "v" to "v.pointee"
print("hello1 \(v.pointee)")
}
}
您只需将呼叫者更改为:
testAdd { $0(&x) }
两个都有用,谢谢。在我看来,第二个解决方案是通过另一个闭包进行修改,它可以是引用类型,这确实需要我花相当长的时间来理解。
testAdd { $0(&x) }