Swift和突变结构

前端之家收集整理的这篇文章主要介绍了Swift和突变结构前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有一些东西,我不完全理解当涉及到在Swift中的值类型的变异。

由于“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)

有没有人知道结构的原因,为什么不能从自己的上下文中改变他们的内容,而内容可以很容易地改变其他地方?

可变性属性标记在存储(常量或变量)上,而不是类型。你可以认为struct有两种模式:mutable和immutable。如果你为一个不可变的存储(我们在Swift中称为let或者constant)分配一个struct值,该值将变为不可变模式,你不能改变值中的任何状态。 (包括调用任何变异方法)

如果该值分配给一个可变存储(我们在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。无论如何,我们仍然需要可变的东西,因为不可变的东西有一些弱点,并讨论这似乎是主题

我希望这有帮助。

猜你在找的Swift相关文章