我已经知道不变性相对于可变性的好处在于能够推理代码并引入更少的错误,尤其是在多线程代码中。不过,在创建结构时,我看不出创建一个完全不可变的结构比创建一个可变的结构有任何好处。
让我们以保存一些分数的结构为例:
struct ScoreKeeper {
var score: Int
}
在这个结构中,我可以更改现有结构变量的分数值
var scoreKeeper = ScoreKeeper(score: 0)
scoreKeeper.score += 5
println(scoreKeeper.score)
// prints 5
不可变版本看起来像这样:
struct ScoreKeeper {
let score: Int
func incrementScoreBy(points: Int) -> ScoreKeeper {
return ScoreKeeper(score: self.score + points)
}
}
及其用法:
let scoreKeeper = ScoreKeeper(score: 0)
let newScoreKeeper = scoreKeeper.incrementScoreBy(5)
println(newScoreKeeper.score)
// prints 5
我没有看到第二种方法相对于第一种方法的好处,因为结构是值类型。如果我传递一个结构体,它总是会被复制。因此,结构是否具有可变属性对我来说似乎并不重要,因为代码的其他部分无论如何都会在单独的副本上工作,从而消除了可变性问题。
不过,我看到有些人使用第二个示例,它需要更多代码,但没有明显的好处。有什么我没有看到的好处吗?
不同的方法将有助于对代码进行不同类型的更改。不可变结构与不可变类对象非常相似,但可变结构和可变类对象有很大不同。因此,如果由于某种原因需要使用类对象来代替,那么使用不可变结构的代码通常可以很容易地进行调整。
另一方面,使用不可变对象通常会使用修改版本替换变量的代码变得更加脆弱,以防向相关类型添加其他属性。例如,如果一个PhoneNumber
类型包括 AreaCode、LocalExchange 和 LocalNumber 的方法以及采用这些参数的构造函数,然后为 Extension 添加“可选”第四个属性,然后是应该通过传递新区号来更改某些电话号码的区号的代码、 LocalExchange 和 LocalNumber 到三参数构造函数将删除每个电话号码的 Extension 属性,而可以直接写入 AreaCode 的代码不会出现该问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)