Что делает свойство вычисляемым свойством в Swift

Давайте начнем с фрагмента кода:

St Foo {
    var proA: Int = 0 { // needs initialization
        willSet {
            print("about to set proA to \(newValue) from \(proA)")
        }
        didSet {
            print("already set proA to \(proA) from \(oldValue)")
        }
    }

    var ProB: Int { // do not needs initialization 
        return 1
    }
}

let foo = Foo()
foo.proA = 23
print(foo.ProB)

Вот некоторые из моих личных представлений о сохраненном и вычисленном свойстве:

a: Свойство только с наблюдателем (willSet и didSet) является не вычисляемым свойством, а хранимым свойством (например, свойство proA в приведенном выше коде).

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

c: setter в некотором роде равен наблюдателю свойства, наблюдатель свойства - просто установщик + наблюдатель до и после мутации.

Вопросы:

1. Интересно, что делает свойство вычисляемым свойством? Верно ли, что если свойство имеет геттер и возвращает его, оно является вычисляемым свойством?

2. Все ли мои представления (а, б и в) верны? Если нет, было бы мило с вашей стороны указать.

3. Почему нельзя инициализировать вычисляемое свойство? (См. Рисунок ниже). И когда я это делаю, компилятор выдает предупреждение. Невозможно вызвать значение типа non-function "int". Что означает эта ошибка?

введите описание изображения здесь

Большое спасибо.

4 ответа

Решение

Во-первых, это переменные, а не свойства. Любая переменная может быть вычисляемой переменной. Свойство является лишь одним из способов использования переменной.

Я думаю, что в целом вы делаете большую ошибку, помещая хранимую переменную вместе с наблюдателями-установщиками рядом с вычисляемой переменной. Они не связаны!

Думайте о вычисляемой переменной как о чем-то, что выглядит и действует как переменная, когда вы ее используете - вы получаете и (возможно) устанавливаете ее - но на самом деле это функция (или пара функций). Это просто компактный способ вызова функции. Вот и все.

С другой стороны, хранимая переменная с наблюдателями - это просто хранимая переменная, у которой также есть несколько наблюдателей.


Хорошо, на ваши вопросы:

  1. Интересно, что делает свойство вычисляемым свойством? Верно ли, что если свойство имеет геттер и возвращает его, это вычисленное свойство?

Да. Это вычисляемая переменная, потому что вы объявили ее, используя синтаксис, который делает ее вычисляемой переменной (с фигурными скобками).

  1. Все ли мои представления (а, б и в) верны? Если не было бы мило с вашей стороны указать

Да. Я думаю, что ваше "c" довольно проницательно: вычисляемая переменная не нуждается в наблюдателе установщика, потому что у него есть (задыхаясь!) Установщик!

  1. Почему нельзя инициализировать вычисляемое свойство? (См. Рисунок ниже). И когда я это делаю, компилятор выдает предупреждение. Невозможно вызвать значение типа non-function "int". Что означает эта ошибка?

Нет никакого смысла в том, что вычисляемая переменная "имеет" значение - оно вычисляется! это просто некоторые функции! - поэтому нет смысла присваивать ему "начальное" значение.

Хранимое свойство - это свойство, значение свойства которого хранится вместе с экземпляром класса или структуры. Значение может быть изменено, но свойство также может быть константой. Таким образом, хранимое свойство может быть таким простым:

var proA: Int
let proB: Int
var proC: Int = 0

Вычисленные свойства не хранят значения. Таким образом, вы не можете присвоить значение вычисляемому свойству. Свойство Computed должно иметь метод получения, который возвращает значение. В широком смысле, вы можете рассматривать вычисляемое свойство как свойство, которое возвращает значение функции.

Пример вычисляемого свойства

var proA: Int {
    return proB * proC
}

Что касается ваших вопросов:

  1. Computed Property - это свойство, которое не хранит значение и содержит метод get для возврата "вычисленного" значения свойства.
  2. a правильно, b вычисляемые свойства не должны иметь инициализации, c если вы имеете в виду willSet и didSet. Да, они как наблюдатели, когда значение свойства изменится и изменилось соответственно
  3. Поскольку значение вычисляемого свойства не сохраняется и никогда не будет использовано, компилятор запрещает это.

Надеюсь это немного поможет.

  1. Интересно, что делает свойство вычисляемым свойством? Верно ли, что если свойство имеет геттер и возвращает его, это вычисленное свойство?

Если вы определите get { } внутри объявления свойства оно превращает это свойство в вычисляемое свойство. И он не может иметь начальное значение, так как при доступе к свойству, он всегда будет вызывать get{} Функция объявлена ​​в свойстве.

  1. Все ли мои представления (а, б и в) верны? Если не было бы мило с вашей стороны указать

    • это правильно
    • б неправильно.

    Вы не можете установить начальное значение для вычисляемого свойства. Потому что, как я объяснил в вопросе 1, он всегда будет возвращать результат get{} когда вам нужен доступ к собственности.

    • с: 50% верно

    сеттер, его также можно использовать как для хранения newValue в другую личную переменную, и вы можете сделать некоторые дополнительные observing логика. Таким образом, чтобы наблюдать изменения значения хранимого свойства, вы используете willSet а также didSetВы можете определить observing логика вычисляемого свойства (которое имеет getter а также setter) на set{} декларация. Но главная цель set {} это сохранить значение в другой переменной или, например, UserDefaults,

  2. Почему нельзя инициализировать вычисляемое свойство? (См. Рисунок ниже). И когда я это делаю, компилятор выдает предупреждение. Невозможно вызвать значение типа non-function "int". Что означает эта ошибка?

    Тот же ответ

    Ваш код приводит в замешательство компилятор. Когда вы устанавливаете начальное значение для свойства в объявлении, компилятор пытается понять его как stored имущество. Но вы также определили get{} для этого свойства, а это значит, что это вычисляемое свойство и должно всегда возвращать 22 когда вы получаете доступ к собственности. Таким образом, вы должны удалить один из двух.

А. Да, свойство с единственным наблюдателем является сохраненным свойством, а не вычисляемым свойством. Наблюдатель свойства Beacuase отслеживает значение свойства, значение которого было инициализировано ранее и теперь меняется, это сохраненное свойство. Это не применимо для вычисляемого свойства, так как не имеет предопределенного значения

б. Свойство computed - это свойство, значение которого зависит от других переменных. Мы должны объявлять только те свойства как вычисляемое свойство, которое необходимо вычислить с использованием значения других переменных, поэтому его значение нельзя инициализировать заранее. например, - если у нас есть 2 переменные a & b. нам нужно их добавочное значение, поэтому используется переменная с именем 'sum', тогда сумма будет объявлена ​​как вычисляемое свойство, а ее блок get{} вернет (a+b) сумму a & b и значение переменной sum. Тогда в этом случае мы не можем заранее инициализировать свойство 'sum', потому что оно будет вычислено с использованием a & b.

с. Сеттер не является наблюдателем, он устанавливает значение другой переменной или выполняет некоторые действия, связанные с другими переменными, тогда как наблюдатель свойства отслеживает изменения в значении своей связанной переменной. например, бессмысленно использовать наблюдатель свойства для переменной "сумма", как описано в пункте б.

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