swift - 不可变结构比可变结构有什么好处?

标签 swift struct functional-programming

我已经知道不变性相对于可变性的优势在于能够推理代码并引入更少的错误,尤其是在多线程代码中。但是,在创建结构时,我看不出有什么比创建完全不可变的结构优于可变结构的好处。

让我们举一个保持分数的结构的例子:

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

我没有看到第二种方法比第一种方法有什么好处,因为结构是值类型。如果我传递一个结构,它总是被复制。因此,结构是否具有可变属性对我来说似乎无关紧要,因为代码的其他部分无论如何都会在单独的副本上工作,从而消除了可变性问题。

不过,我看到有些人使用第二个示例,这需要更多代码而没有明显的好处。有什么我没有看到的好处吗?

最佳答案

不同的方法将有助于对代码进行不同类型的更改。不可变结构与不可变类对象非常相似,但可变结构和可变类对象有很大不同。因此,如果出于某种原因有必要改用类对象,使用不可变结构的代码通常可以很容易地进行调整。

另一方面,使用不可变对象(immutable对象)通常会使用修改后的版本替换变量的代码更加脆弱,以防向相关类型添加其他属性。例如,如果 PhoneNumber 类型包括 AreaCode、LocalExchange 和 LocalNumber 的方法以及采用这些参数的构造函数,然后为 Extension 添加“可选”第四个属性,那么应该更改的代码通过将新区号 LocalExchange 和 LocalNumber 传递给三参数构造函数,某些电话号码的区号将删除每个电话号码的 Extension 属性,而可以直接写入 AreaCode 的代码不会有这个问题.

关于swift - 不可变结构比可变结构有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29589007/

相关文章:

与枚举匹配的 Swift guard 语句模式

c++ - 在 C++ 中按结构成员对列表进行排序

c - C中的结构指针

functional-programming - 方案/ Racket : most idiomatic way to append single element to end of list

haskell - 如何摆脱这种歧义?

functional-programming - (调用/抄送): What exactly is continuation?

ios - 是否可以使用 Swift 创建自定义键盘而不强制用户通过设置屏幕附加它?

ios - 尝试解析 json 时出现错误 : use of undeclared type 'Foundation'

ios - 用户在 swift 中设置通知时间

单个 C 头文件中的循环依赖。需要前向声明吗?