Phương thức thay đổi
Thuộc phần Lập trình hướng đối tượng trong hành trình Swift của Coddy. Bài học 9 trên 57.
Một phương thức của struct thay đổi thuộc tính phải được đánh dấu là mutating. Nếu không có từ khóa này, phương thức sẽ không biên dịch được, vì các phương thức của kiểu giá trị xem self là hằng số:
struct Counter {
var count = 0
mutating func increment() {
count += 1
}
}
var c = Counter()
c.increment()
c.increment()
print(c.count)Đầu ra:
2Chỉ có thể gọi phương thức làm thay đổi giá trị trên một var. Với hằng số let, lời gọi này không biên dịch được vì toàn bộ giá trị đã cố định:
var a = Counter()
a.increment() // hợp lệ
let b = Counter()
// b.increment() // lỗi: b là hằng số khai báo bằng letCác phương thức chỉ đọc thuộc tính không làm thay đổi đối tượng và cũng hoạt động với hằng số. Một thiết kế tốt sẽ giới hạn các thay đổi trong một vài phương thức làm thay đổi đối tượng:
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)Đầu ra:
8
3Một phương thức thay đổi có thể thay thế hoàn toàn self, rất tiện khi bạn muốn đặt lại một giá trị:
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)Đầu ra:
0Thử thách
DễHoàn thiện cấu trúc Wallet. add(_:) và spend(_:) có thể thay đổi đối tượng: spend chỉ trừ tiền khi còn đủ tiền và trả về kết quả cho biết có trừ tiền hay không. report() không thay đổi đối tượng và trả về balance 40.
Code được cung cấp đọc các lệnh +n và -n, áp dụng chúng cho một ví var, in ra denied nếu từ chối yêu cầu chi tiền, rồi cuối cùng in ra report().
Viết code trong Wallet.swift. main.swift chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
// Đoạn code đầu vào/đầu ra đã cho: giữ nguyên
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())
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpPhương thức và selfHàm khởi tạoLớp là tham chiếuÔn tập: Thẻ thư viện2Struct và kiểu giá trị
StructNgữ nghĩa giá trịPhương thức thay đổiStruct hay classÔn tập: mặt hàng trong kho5Kế thừa
Lớp conGhi đè phương thứcHàm khởi tạo và superfinal và hệ phân cấpÔn tập: hệ phân cấp nhân viên8Các giao thức tiêu chuẩn
CustomStringConvertibleEquatableComparableHashableÔn tập: Sắp xếp tùy chỉnhTự luyện tập: Playground Swift