Menu
Coddy logo textTech

Tylko do odczytu z zewnątrz

Część sekcji Programowanie obiektowe ścieżki Swift w Coddy. Lekcja 18 z 57.

Często kod zewnętrzny powinien móc odczytywać właściwość, ale nie zmieniać jej. private(set) pozostawia getter na zwykłym poziomie dostępu, a ustawia setter jako prywatny:

struct Counter {
    private(set) var count = 0

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

var c = Counter()
c.increment()
print(c.count)
// c.count = 99   // błąd: setter jest prywatny

Wynik:

1

Pasuje to do wartości, które mogą zmieniać się wyłącznie zgodnie z określoną regułą, na przykład wyniku, który może rosnąć tylko w wyniku prawidłowych działań:

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)

Wynik:

13
[10, 3]

Właściwość let jest tylko do odczytu dla wszystkich po utworzeniu instancji, także dla własnych metod danego typu. private(set) var pozostaje możliwa do zmiany wewnątrz typu. Wybierz let dla wartości, które nigdy się nie zmieniają po utworzeniu:

class Order {
    let id: Int                 // nigdy się nie zmienia
    private(set) var status = "new"   // zmienia się, ale tylko wewnątrz Order
    init(id: Int) { self.id = id }
    func ship() { status = "shipped" }
}

Obliczana właściwość tylko do odczytu to kolejny sposób na udostępnianie informacji bez umożliwiania ich zmiany, ponieważ w ogóle nie ma settera:

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

Wynik:

2 items, total 10
challenge icon

Wyzwanie

Łatwy

Uzupełnij klasę Elevator. Wartości floor i trips można odczytywać z zewnątrz, ale zmieniać może je tylko klasa (private(set)). goTo(_:) porusza się między piętrem 0 a topFloor: prawidłowy ruch na inne piętro aktualizuje floor, zwiększa trips o 1 i zwraca true; nieprawidłowy ruch lub ruch na to samo piętro zwraca false.

Dostarczony kod odczytuje najwyższe piętro, a następnie piętra docelowe. Po wykonaniu ruchu wyświetla floor 3 lub stay 3, jeśli ruch został odrzucony, a na końcu trips: wraz z liczbą przejazdów.

Twój kod umieść w pliku Elevator.swift. Plik main.swift zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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 iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Edytor online Swift