可变性属性标记在存储(常量或变量)上,而不是类型上。你可以认为 struct 有两种模式:mutable and 不可变的。如果将结构体值分配给不可变存储(我们称之为let
or constant在 Swift 中)该值变为不可变模式,并且您无法更改该值中的任何状态。 (包括调用任何变异方法)
如果该值被分配给可变存储(我们称之为var
or variable在 Swift 中),你可以自由修改它们的状态,并且允许调用变异方法。
此外,类没有这种不可变/可变模式。 IMO,这是因为类通常用于表示可参考的实体。可引用实体通常是可变的,因为很难以不可变的方式创建和管理实体的引用图并具有适当的性能。他们可能会在以后添加此功能,但至少现在不会。
对于 Objective-C 程序员来说,可变/不可变的概念是非常熟悉的。在 Objective-C 中,每个概念都有两个独立的类,但在 Swift 中,您可以使用一个结构来完成此操作。一半工作。
对于C/C++程序员来说,这也是非常熟悉的概念。这正是const
C/C++ 中的关键字 do。
此外,不可变值可以得到很好的优化。理论上,Swift 编译器(或 LLVM)可以对传递的值执行复制省略let
,就像在 C++ 中一样。如果您明智地使用不可变结构,它将优于引用计数类。
Update
正如@Joseph 声称的那样,这并没有提供why,我补充一点。
结构体有两种方法。plain and mutating方法。Plain方法意味着不可变(或不可变)。这种分离的存在只是为了支持不可变的语义。处于不可变模式的对象根本不应该改变其状态。
那么,不可变方法必须保证这一点语义不变性。这意味着它不应该改变任何内部值。因此编译器不允许在不可变方法中对其自身进行任何状态更改。相反,变异方法可以自由修改状态。
然后,你可能会有一个疑问为什么默认是不可变的?这是因为很难预测变异值的未来状态,而这通常成为令人头痛和错误的主要来源。许多人同意解决方案是避免可变的东西,然后默认不可变几十年来,它一直是 C/C++ 家族语言及其派生语言的首选。
See 纯功能风格 http://en.wikipedia.org/wiki/Purely_functional更多细节。不管怎样,我们仍然需要可变的东西,因为不可变的东西有一些弱点,讨论它们似乎超出了主题。