摘录了一部分原文的内容记录一下,观点未必彻底正确,可是有参考的必要。git
函数式编程中有个很重要的概念:不可变。可是在实际的开发过程当中,又经常为这三个字所困扰:对象的状态总归是常常要变化的,如何才能既可变又不可变?github
在函数式编程里,对于状态的改变,咱们能够简单的返回一个新的对象,而不是修改对象的状态。编程
不妨先看一看 mutating
的方式:swift
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 框架里,“不可变”无疑是充满挑战的,并且彻底的“不可变”也是不可能的。函数
即便如此,我以为从这件事情中也受益不少,至少引导我进行了一些良心的思考。这便足够了。单元测试
参考文档:测试