变更方法
本课属于 Coddy Swift 学习旅程的“面向对象编程”单元。第 9 课,共 57 课。
会更改属性的结构体方法必须标记为 mutating。如果没有这个关键字,方法就无法编译,因为值类型的方法会将 self 视为常量:
struct Counter {
var count = 0
mutating func increment() {
count += 1
}
}
var c = Counter()
c.increment()
c.increment()
print(c.count)输出:
2只能对 var 调用可变方法。对 let 常量调用不会通过编译,因为整个值是固定的:
var a = Counter()
a.increment() // 没问题
let b = Counter()
// b.increment() // 错误:b 是 let 常量只读取属性的方法不会修改对象,常量也可以使用这些方法。好的设计会将更改集中在少数会修改对象的方法中:
struct Stack {
var items: [Int] = []
mutating func push(_ x: Int) { items.append(x) }
mutating func pop() -> Int? { items.popLast() }
func peek() -> Int? { items.last }
}
var s = Stack()
s.push(3)
s.push(8)
print(s.pop() ?? -1)
print(s.peek() ?? -1)输出:
8
3变异方法可以完全替换 self,这在重置值时很方便:
struct Score {
var points = 0
var bonus = 0
mutating func reset() {
self = Score()
}
}
var s = Score(points: 10, bonus: 3)
s.reset()
print(s.points + s.bonus)输出:
0挑战
简单完成 Wallet 结构体。add(_:) 和 spend(_:) 是 mutating 方法:spend 只会在余额充足时扣款,并返回是否扣款成功。report() 不会修改对象,并返回 balance 40。
提供的代码会读取 +n 和 -n 命令,并将它们应用到同一个 var 钱包上。遇到拒绝的支出时,代码会打印 denied,最后打印 report()。
你的代码应写在 Wallet.swift 中。main.swift 包含提供的输入/输出代码,不能编辑。
亲手试试
// 提供的输入/输出代码:保持原样
var input: [String] = []
while let line = readLine() { input.append(line) }
var wallet = Wallet()
for cmd in input {
let amount = Int(cmd.dropFirst())!
if cmd.hasPrefix("+") {
wallet.add(amount)
} else if !wallet.spend(amount) {
print("denied")
}
}
print(wallet.report())
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Swift 在线编辑器