gpt4 book ai didi

ios - Swift 中的 didSet 对 mutating func 有奇怪的链式 react

转载 作者:IT王子 更新时间:2023-10-29 05:17:38 24 4
gpt4 key购买 nike

我刚刚了解到 mutating func 只是一个第一个参数为 inout 的柯里化(Currying)函数,所以下面的代码将起作用并将 firstName 更改为 "John"

struct Person {
var firstName = "Matt"

mutating func changeName(fn: String) {
firstName = fn
}
}
var p = Person()
let changer = Person.changeName
changer(&p)("John")
p.firstName

但是当我像下面这样将属性观察器添加到 p 时发生了奇怪的事情,你可以看到 firstName 仍然是“Matt”,为什么? enter image description here

最佳答案

一个有趣的注意事项是观察者被调用在柯里化(Currying)的 setter 被调用之前:

struct Person {
var firstName = "Matt"

mutating func changeName(fn: String) {
firstName = fn
}
}

var p: Person = Person() {
didSet {
print("p was set")
}
}

print("1: \(p.firstName)")
let changer = Person.changeName
print("2: \(p.firstName)")
let setter = changer(&p)
print("3: \(p.firstName)")
setter("John")
print("4: \(p.firstName)")
p.changeName("John")
print("5: \(p.firstName)")

这打印:

1: Matt
2: Matt
p was set
3: Matt
4: Matt
p was set
5: John

所以看起来在 inout 结构上获取 setter 方法执行实际的突变。这可以通过 inout 参数在语义上的工作方式来解释:当参数被传递给函数时,它的值被复制到函数可以改变它的地方。当函数返回时,值被复制回原来的地方,触发 setter 观察者一次,无论值是否发生变化。

当我们将获取预填充 curried setter 的方式更改为:

let setter = p.changeName

...编译器对象:

error: partial application of 'mutating' method is not allowed

编译器似乎明白关闭 inout 值是个坏主意,因为它基本上是在引用值类型。

闭包允许您随时更改结构的值,即使编译器假定它是常量。为了防止这种不幸的情况,编译器只是禁止关闭 inout。

您发现了一个可以愚弄编译器并绕过诊断的案例。这似乎是一个错误,应该归档。

简短版:

struct Foo {
mutating func foo() {}
}

var f = Foo()
let m = Foo.foo
let s = m(&f)

最后两行中的一行应该发出一个错误,类似于 let x = f.foo

关于ios - Swift 中的 didSet 对 mutating func 有奇怪的链式 react ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35555601/

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