外部只读
本课属于 Coddy Swift 学习旅程的“面向对象编程”单元。第 18 课,共 57 课。
通常,代码外部应该可以读取属性,但不能更改属性。private(set)会让 getter 保持正常的访问级别,只将 setter 设为私有:
struct Counter {
private(set) var count = 0
mutating func increment() {
count += 1
}
}
var c = Counter()
c.increment()
print(c.count)
// c.count = 99 // 错误:setter 是私有的输出:
1这适用于只能通过规则改变的值,例如只能通过有效操作增加的分数:
class Player {
let name: String
private(set) var score = 0
private(set) var history: [Int] = []
init(name: String) { self.name = name }
func award(_ points: Int) {
guard points > 0 else { return }
score += points
history.append(points)
}
}
let p = Player(name: "Ada")
p.award(10)
p.award(-5)
p.award(3)
print(p.score)
print(p.history)输出:
13
[10, 3]let 属性在实例创建后对所有人都是只读的,包括类型自身的方法。private(set) var 在类型内部仍然可以修改。对于创建后永远不会改变的值,请选择 let:
class Order {
let id: Int // 永远不会改变
private(set) var status = "new" // 可以改变,但只能在 Order 内部改变
init(id: Int) { self.id = id }
func ship() { status = "shipped" }
}只读计算属性是另一种公开信息的方式,它不允许修改,因为它完全没有 setter:
struct Cart {
private var prices: [Int] = []
var total: Int { prices.reduce(0, +) }
var count: Int { prices.count }
mutating func add(_ price: Int) { prices.append(price) }
}
var cart = Cart()
cart.add(4)
cart.add(6)
print("\(cart.count) items, total \(cart.total)")输出:
2 items, total 10挑战
简单完成 Elevator 类。外部可以读取 floor 和 trips,但只有这个类可以修改它们(private(set))。goTo(_:) 可以在第 0 层和 topFloor 之间移动:如果移动有效且目标楼层不同,就更新 floor,将 trips 加 1,并返回 true;如果移动无效或目标楼层相同,则返回 false。
提供的代码会读取顶层楼层,然后读取目标楼层。移动成功后会输出 floor 3,移动被拒绝时会输出 stay 3,最后会输出 trips: 和移动次数。
你的代码写在 Elevator.swift 中。main.swift 中包含提供的输入输出代码,不能编辑。
亲手试试
// 提供的输入输出代码:保持原样
var input: [String] = []
while let line = readLine() { input.append(line) }
let lift = Elevator(topFloor: Int(input[0])!)
for line in input.dropFirst() {
let moved = lift.goTo(Int(line)!)
print("\(moved ? "floor" : "stay") \(lift.floor)")
}
print("trips: \(lift.trips)")
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Swift 在线编辑器