如何从转义闭包中更改 inout 参数?
How can I change an inout parameter from within a escaping closure?
我试图从转义闭包中修改函数参数,如下所示:
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()
}
我想知道除了将其作为 class 对象的引用类型之外,是否还有另一种方法可以让转义闭包更改周围变量(作为函数的 inout 参数)。
inout
被指定为具有“复制输入复制输出”行为。 x
的值在您调用该函数时被复制。在函数体中,可以修改 x
的副本,或其他任何内容。然后,当函数returns时,将副本再次复制,并赋值给原来的x
。 “按引用调用”可以作为优化发生。
这解释了为什么不能在转义闭包中修改 inout
参数。 swift 编译器不可能知道每个转义闭包 returns 何时将修改后的值复制回来。
您可以使用实际指针:
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)")
}
}
或者,如果你不喜欢指针,你也可以这样做(改编自my other answer):
func testAdd(modifyV: @escaping ((inout Int) -> Void) -> Void) {
addCompletion{
modifyV { v in // here you can change v however you like!
v = 1
print("hello1 \(v)")
}
}
}
您只需要将来电者改为:
testAdd { [=12=](&x) }
我试图从转义闭包中修改函数参数,如下所示:
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()
}
我想知道除了将其作为 class 对象的引用类型之外,是否还有另一种方法可以让转义闭包更改周围变量(作为函数的 inout 参数)。
inout
被指定为具有“复制输入复制输出”行为。 x
的值在您调用该函数时被复制。在函数体中,可以修改 x
的副本,或其他任何内容。然后,当函数returns时,将副本再次复制,并赋值给原来的x
。 “按引用调用”可以作为优化发生。
这解释了为什么不能在转义闭包中修改 inout
参数。 swift 编译器不可能知道每个转义闭包 returns 何时将修改后的值复制回来。
您可以使用实际指针:
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)")
}
}
或者,如果你不喜欢指针,你也可以这样做(改编自my other answer):
func testAdd(modifyV: @escaping ((inout Int) -> Void) -> Void) {
addCompletion{
modifyV { v in // here you can change v however you like!
v = 1
print("hello1 \(v)")
}
}
}
您只需要将来电者改为:
testAdd { [=12=](&x) }