摘录了一部分 原文 的内容记录一下,观点未必完全正确,但是有参考的必要。
函数式编程中有个很重要的概念:不可变。但是在实际的开发过程中,又常常为这三个字所困扰:对象的状态总归是经常要变化的,如何才能既可变又不可变?
在函数式编程里,对于状态的改变,我们可以简单的返回一个新的对象,而不是修改对象的状态。
不妨先看一看 mutating
的方式:
class Scorekeeper { var runningScore: Int init (score: Int = 0) { self.runningScore = score } func incrementScoreBy(points: Int) { runningScore += points } } let scoreKeeper = Scorekeeper() scoreKeeper.incrementScoreBy(5) println(scoreKeeper.runningScore) // prints 5
再看一下 immutable
的方式:
class Scorekeeper { let runningScore: Int init (score: Int = 0) { self.runningScore = score } func incrementScoreBy(points: Int) -> Scorekeeper { return Scorekeeper(score: self.runningScore + points) } } let scorekeeper = Scorekeeper() let scorekeeperWithIncreasedScore = scorekeeper.incrementScoreBy(5) println(scorekeeperWithIncreasedScore.runningScore)
对比一下上面的两个例子:
var
定义 Scorekeeper
实例对象,因为它必须是可变的。 let
定于 Scorekeeper
实例对象,因为这个对象没有任何变化。 scorekeeper
这个实例,那么现在有两种方式改变 runningScore
:一种是重新给 runningScore
赋值,另一种是调用 incrementScoreBy()
这个方法。不管是哪一种方法,因为状态是可编辑的,所以都有可能会导致不可预知的问题。 runningScore
是无法直接编辑的 (它是常量) 。而 incrementScoreBy()
返回的是一个全新的变量,所以所有的持有 scorekeeper
的外部对象在访问的时候都能获取到理想的结果。 incrementScoreBy()
方法没有返回值。想象一下如果我要写个单元测试,第一眼看过去很容易不知所措。 incrementScoreBy()
返回一个新的对象,单元测试对我来说就清晰多了。 避免直接的状态变化让我受益匪浅,在现有的 iOS 框架里,“不可变”无疑是充满挑战的,而且完全的“不可变”也是不可能的。
即使如此,我觉得从这件事情中也受益很多,至少引导我进行了一些良心的思考。这便足够了。
参考文档: