Menu
Coddy logo textTech

Только чтение извне

Часть раздела Объектно-ориентированное программирование путешествия по Swift на Coddy. Урок 18 из 57.

Часто внешний код должен читать свойство, но не изменять его. private(set) оставляет геттер с обычным уровнем доступа, а приватным делает только сеттер:

struct Counter {
    private(set) var count = 0

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

var c = Counter()
c.increment()
print(c.count)
// c.count = 99   // ошибка: сеттер является приватным

Вывод:

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
challenge icon

Задание

Легко

Завершите класс 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)")
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Песочница Swift