gpt4 book ai didi

swift - 在闭包中捕获结构引用不允许发生突变

转载 作者:搜寻专家 更新时间:2023-10-31 22:32:21 25 4
gpt4 key购买 nike

我想看看我是否可以为我的模型使用结构体,并且正在尝试这个。当我调用 vm.testClosure() 时,它不会更改 x 的值,我不确定为什么。

struct Model
{
var x = 10.0
}


var m = Model()

class ViewModel
{
let testClosure:() -> ()

init(inout model: Model)
{
testClosure =
{
() -> () in
model.x = 30.5
}
}
}



var vm = ViewModel(model:&m)

m.x

vm.testClosure()

m.x

最佳答案

inout 参数不是对值类型的引用——它只是该值类型的影子副本,当函数返回。

您的代码中发生的事情是您的 inout 变量正在逃离函数的生命周期(通过在闭包中捕获然后存储)——这意味着对 inout 的任何更改 函数返回后的变量将永远不会反射(reflect)在闭包之外。

由于对 inout 参数的这种常见误解,有 been a Swift Evolution proposal因为只允许 inout 参数被 @noescape 闭包捕获。从 Swift 3 开始,您当前的代码将无法编译。

如果你真的需要在你的代码中传递引用——那么你应该使用引用类型(让你的Model成为class)。虽然我怀疑您可能能够重构您的逻辑以避免首先传递引用(但是,如果没有看到您的实际代码,就不可能提出建议)。

(编辑:自发布此答案以来,inout 参数现在可以编译为引用传递,这可以通过查看 SIL 或 IR 看出emitted。但是你不能这样对待它们,因为不能保证无论如何调用者的值在函数调用后仍然有效。)

关于swift - 在闭包中捕获结构引用不允许发生突变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37043070/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com