1

使用游乐场。

我有以下结构:

struct Foo {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

我将其中的一个实例声明为属性观察者,默认值为 the 的“James”name和 的 33 age

var myFoo = Foo(name: "James", age: 33) {
    willSet {
        print("my foo will be: \(newValue)")
    }
    didSet {
        print("my foo was: \(oldValue)")
    }
}

尝试编辑name实例时:

myFoo.name = "John"

我可以在日志上看到:

我的 foo 将是: Foo(name: "John", age: 33)

我的 foo 是:Foo(姓名:“James”,年龄:33)

这是我的期望。但是,当声明Foo为类而不是结构时:class Foo并运行完全相同的代码,日志上不会出现任何内容。

背后的原因是什么?

4

1 回答 1

2

因为类是引用类型,而结构是值类型。

  • 假设 Foo 是一个类。myFoo只是一个参考。说myFoo.name = "John"改变原地的对象;没有为 分配新值myFoo,因此 setter 观察者没有什么可观察的。

  • 假设 Foo 是一个结构。那是一种价值类型。它不能原地变异。因此,sayingmyFoo.name = "John"实际上将变量中的结构替换myFoo为新结构;设置变量并触发 setter 观察者。


这也是为什么你可以说myFoo.name = "John"一个类即使myFoo被声明为let(即对象只是在适当的地方发生了变异),但你不能用一个结构来做到这一点——你必须已经声明myFoo了,var以便变量值可以是更换。

于 2018-04-12T22:01:24.687 回答