使用游乐场。
我有以下结构:
struct Foo {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
我声明了一个来自它的实例作为属性观察者,默认值为" 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(姓名:" John",年龄:33岁)
我的foo是:Foo(姓名:" James",年龄:33岁)
这是我的期望。但是,在将Foo
声明为类而不是结构:class Foo
并运行完全相同的代码时,日志中不会显示任何内容。
背后的原因是什么?
答案 0 :(得分:2)
因为类是引用类型,而结构是值类型。
假设Foo是一个类。 myFoo
仅仅是一个参考。说myFoo.name = "John"
将对象变异到位;没有为myFoo
分配新值,因此setter观察者无需观察。
假设Foo是一个结构。这是一种价值类型。它不能在适当的位置进行变异。因此,说myFoo.name = "John"
实际上用新结构替换变量myFoo
中的结构;设置变量并设置setter观察者。
这就是为什么即使用myFoo.name = "John"
声明myFoo
(即对象只是在适当位置发生变异),你也可以为一个类说let
,但是你不能这样做使用结构 - 您必须使用myFoo
声明var
,以便可以替换变量值。