由于“Swift编程语言”iBook指出:默认情况下,值类型的属性不能在其实例方法内修改。
为了使这个可能,我们可以在struct和枚举中使用mutating关键字声明方法。
对我来说不完全清楚的事情是这样的:
您可以从结构外部更改var,但不能从其自己的方法中更改它。这对我来说似乎是不直观的,就像在面向对象的语言中,你通常试图封装变量,以便它们只能从内部改变。使用结构体这似乎是另一种方式。详细说明,这里是一个代码片段:
struct Point { var x = 0,y = 0 mutating func moveToX(x: Int,andY y:Int) { //Needs to be a mutating method in order to work self.x = x self.y = y } } var p = Point(x: 1,y: 2) p.x = 3 //Works from outside the struct! p.moveToX(5,andY: 5)
如果该值分配给一个可变存储(我们在Swift中称为var或variable),则可以自由修改它们的状态,并允许调用mutating方法。
另外,类没有这个不可变/可变模式。 IMO,这是因为类通常用于表示可引用实体。并且可引用实体通常是可变的,因为很难以不可变的方式以适当的性能来制作和管理实体的引用图。他们可能稍后添加此功能,但至少现在不是。
对于Objective-C程序员,可变/不可变的概念是非常熟悉的。在Objective-C中,我们为每个概念都有两个分离的类,但是在Swift中,你可以使用一个结构体。半工作。
对于C/C++程序员,这也是非常熟悉的概念。这正是const关键字在C/C++中做的。
另外,不可变的值可以非常好地优化。理论上,Swift编译器(或LLVM)可以对由let传递的值执行复制删除,就像C一样。如果明智地使用不可变的结构,它将优于引用计数的类。
更新
正如@Joseph声称这不提供为什么,我添加一点。
Structs有两种方法。平原和突变方法。平原法意味着不可变的(或非突变的)。这种分离只存在于支持不可变语义。处于不可变模式的对象不应该改变它的状态。
然后,不可变方法必须保证这种语义不变性。这意味着它不应该改变任何内部价值。因此,编译器不允许在不可变方法中的任何状态更改。相反,突变方法可以自由修改状态。
然后,你可能有一个为什么不可变是默认的问题?这是因为很难预测突变值的未来状态,这通常成为头痛和错误的主要来源。许多人同意,解决方案是避免可变的东西,然后不可变默认情况下在C/C++家族语言及其派生的愿望清单几十年。
有关详细信息,请参阅purely functional style。无论如何,我们仍然需要可变的东西,因为不可变的东西有一些弱点,并讨论这似乎是主题。
我希望这有帮助。