Menu
CoddyTech

Chỉ đọc từ bên ngoà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 18 trên 57.

Thông thường, code bên ngoài nên đọc một thuộc tính nhưng không thay đổi thuộc tính đó. private(set) giữ getter ở mức thông thường và chỉ đặt setter ở chế độ private:

struct Counter {
    private(set) var count = 0

    mutating func increment() {
        count += 1
    }
}

var c = Counter()
c.increment()
print(c.count)
// c.count = 99   // lỗi: phương thức setter là private

Đầu ra:

1

Cách này phù hợp với các giá trị chỉ được thay đổi theo một quy tắc, chẳng hạn như điểm số chỉ tăng lên thông qua các hành động hợp lệ:

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)

Đầu ra:

13
[10, 3]

Thuộc tính let chỉ có thể đọc sau khi đối tượng được tạo, kể cả trong các phương thức của chính kiểu đó. private(set) var vẫn có thể thay đổi bên trong kiểu. Hãy chọn let cho các giá trị không bao giờ thay đổi sau khi được tạo:

class Order {
    let id: Int                 // không bao giờ thay đổi
    private(set) var status = "new"   // có thể thay đổi, nhưng chỉ bên trong Order
    init(id: Int) { self.id = id }
    func ship() { status = "shipped" }
}

Thuộc tính được tính chỉ đọc là một cách khác để cung cấp thông tin mà không cho phép thay đổi, vì thuộc tính này hoàn toàn không có hàm thiết lập:

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)")

Đầu ra:

2 items, total 10
challenge icon

Thử thách

Dễ

Hoàn thiện lớp (class) Elevator. Bạn có thể đọc floor và trips từ bên ngoài, nhưng chỉ lớp mới có thể thay đổi chúng (private(set)). goTo(_:) di chuyển giữa tầng 0 và topFloor: nếu di chuyển hợp lệ đến một tầng khác, hàm sẽ cập nhật floor, tăng trips thêm 1 và trả về true; nếu di chuyển không hợp lệ hoặc đến cùng tầng, hàm trả về false.

Code được cung cấp đọc tầng cao nhất rồi đọc các tầng đích. Code in ra floor 3 sau khi di chuyển hoặc stay 3 khi yêu cầu di chuyển bị từ chối, rồi cuối cùng in trips: kèm theo số lượt di chuyển.

Code của bạn nằm trong Elevator.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 có sẵn: giữ nguyên
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)")
quiz iconTự kiểm tra

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

Tự luyện tập: Playground Swift