我试图从转义闭包中修改函数的参数,如下所示:
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
被指定为具有“拷入拷出”行为。的价值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)")
}
}
或者,如果您不喜欢指针,您也可以执行此技巧(改编自我的另一个答案 https://stackoverflow.com/a/62658325/5133585):
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 { $0(&x) }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)