非变更式替代方案
返回新值,而不是原地修改。
非变更式替代方案 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
返回值而不是直接变更
非变更方法不会直接更改实例,而是返回一个已经应用更改的全新值。
struct Counter {
var value: Int
func incremented() -> Counter {
return Counter(value: value + 1)
}
}
let c = Counter(value: 0)
let next = c.incremented()
print(c.value, next.value)原值保持不变
由于没有进行任何变更,原值会被保留,同时生成一个新值。
struct Vector {
var x: Int
var y: Int
func scaled(by factor: Int) -> Vector {
return Vector(x: x * factor, y: y * factor)
}
}
let v = Vector(x: 2, y: 3)
let big = v.scaled(by: 10)
print(v.x, v.y, big.x, big.y)可用于常量实例
非变更方法不会更改接收调用的实例,因此可以在 let 常量上调用。
struct Money {
var cents: Int
func plus(_ other: Int) -> Money {
return Money(cents: cents + other)
}
}
let m = Money(cents: 100)
print(m.plus(50).cents)命名约定
Swift 的约定是:变更方法使用祈使动词(sort),非变更方法使用过去分词或 -ed/-ing 形式(sorted)。
var nums = [3, 1, 2]
let ordered = nums.sorted()
nums.sort()
print(ordered, nums)sorted 与 sort
标准库遵循这一约定:sorted() 返回一个新数组,而 sort() 会直接变更原数组。
let a = [5, 2, 8, 1]
let b = a.sorted()
print(a)
print(b)reversed 与反向操作
同样,reversed() 不会进行变更。这里使用 Array 将结果具体化。
let a = [1, 2, 3]
let b = Array(a.reversed())
print(a, b)串联非变更调用
非变更方法会返回值,因此您可以流畅地串联调用它们。
let result = [4, 2, 9, 1].sorted().map { $0 * 2 }
print(result)函数式风格
返回新值而不是直接变更,支持一种易于测试和推理的函数式风格。
struct Account {
var balance: Int
func deposited(_ n: Int) -> Account {
return Account(balance: balance + n)
}
}
let a0 = Account(balance: 0)
let a1 = a0.deposited(100).deposited(50)
print(a0.balance, a1.balance)避免共享状态错误
生成新值可以避免意外的共享变更,这一点在线程之间尤其有价值。
struct Settings {
var volume: Int
func with(volume newVolume: Int) -> Settings {
return Settings(volume: newVolume)
}
}
let base = Settings(volume: 5)
let loud = base.with(volume: 11)
print(base.volume, loud.volume)何时应改为直接变更
如果您在循环中反复更新同一个实例,直接变更通常比创建许多副本更高效。
var total = 0
for n in 1...5 {
total += n
}
print(total)同时提供两种形式
设计良好的类型有时会像标准库一样同时提供两种形式,让调用者选择直接变更或生成新值。
struct Text {
var value: String
func uppercased() -> Text {
return Text(value: value.uppercased())
}
mutating func uppercase() {
value = value.uppercased()
}
}
var t = Text(value: "hi")
let u = t.uppercased()
t.uppercase()
print(u.value, t.value)快速检查
测试非变更设计。
回顾
作为直接变更的替代方案,非变更方法会返回一个已应用更改的新值,保留原值不变,并且可以用于 let 实例。Swift 的约定是将祈使名称(sort)与 -ed/-ing 名称(sorted)配对。
let a = [3, 1, 2]
let b = a.sorted()
print(a, b)常见问题解答
「非变更式替代方案」课时是免费的吗?
是的 — 「非变更式替代方案」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「非变更式替代方案」这节课中我会学到什么?
返回新值,而不是原地修改。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「非变更式替代方案」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。