Почему обозреватель недвижимости не работает с классами?

Использование детской площадки.

У меня есть следующая структура:

struct Foo {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

Я объявил экземпляр из него в качестве наблюдателя свойства со значениями по умолчанию как "Джеймс" для name и 33 для age:

var myFoo = Foo(name: "James", age: 33) {
    willSet {
        print("my foo will be: \(newValue)")
    }
    didSet {
        print("my foo was: \(oldValue)")
    }
}

При попытке отредактировать name из экземпляра:

myFoo.name = "John"

Я мог видеть в журнале:

Мой Фу будет: Фу (имя: "Джон", возраст: 33)

мой Фу был: Фу (имя: "Джеймс", возраст: 33)

что я и ожидал Однако при объявлении Foo как класс вместо структуры: class Foo и запустить точно такой же код, ничего не появится в журнале.

В чем причина этого?

1 ответ

Решение

Потому что класс является ссылочным типом, а структура является типом значения.

  • Предположим, что Foo класс. myFoo это просто ссылка. поговорка myFoo.name = "John" мутирует объект на месте; новое значение не назначается myFooПоэтому наблюдателю-установщику нечего наблюдать.

  • Предположим, что Foo является структурой. Это тип значения. Это не может быть изменено на месте. Таким образом, говоря myFoo.name = "John" фактически заменяет структуру в переменной myFoo с новой структурой; который устанавливает переменную и запускает наблюдатель сеттера.


Вот почему вы можете сказать myFoo.name = "John" для класса, даже если myFoo был объявлен с let (т.е. объект просто мутирует на месте), но вы не можете сделать это со структурой - вы должны были объявить myFoo с var так что значение переменной можно заменить.

Другие вопросы по тегам