Что делает свойство вычисляемым свойством в 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 ответа
Во-первых, это переменные, а не свойства. Любая переменная может быть вычисляемой переменной. Свойство является лишь одним из способов использования переменной.
Я думаю, что в целом вы делаете большую ошибку, помещая хранимую переменную вместе с наблюдателями-установщиками рядом с вычисляемой переменной. Они не связаны!
Думайте о вычисляемой переменной как о чем-то, что выглядит и действует как переменная, когда вы ее используете - вы получаете и (возможно) устанавливаете ее - но на самом деле это функция (или пара функций). Это просто компактный способ вызова функции. Вот и все.
С другой стороны, хранимая переменная с наблюдателями - это просто хранимая переменная, у которой также есть несколько наблюдателей.
Хорошо, на ваши вопросы:
- Интересно, что делает свойство вычисляемым свойством? Верно ли, что если свойство имеет геттер и возвращает его, это вычисленное свойство?
Да. Это вычисляемая переменная, потому что вы объявили ее, используя синтаксис, который делает ее вычисляемой переменной (с фигурными скобками).
- Все ли мои представления (а, б и в) верны? Если не было бы мило с вашей стороны указать
Да. Я думаю, что ваше "c" довольно проницательно: вычисляемая переменная не нуждается в наблюдателе установщика, потому что у него есть (задыхаясь!) Установщик!
- Почему нельзя инициализировать вычисляемое свойство? (См. Рисунок ниже). И когда я это делаю, компилятор выдает предупреждение. Невозможно вызвать значение типа non-function "int". Что означает эта ошибка?
Нет никакого смысла в том, что вычисляемая переменная "имеет" значение - оно вычисляется! это просто некоторые функции! - поэтому нет смысла присваивать ему "начальное" значение.
Хранимое свойство - это свойство, значение свойства которого хранится вместе с экземпляром класса или структуры. Значение может быть изменено, но свойство также может быть константой. Таким образом, хранимое свойство может быть таким простым:
var proA: Int
let proB: Int
var proC: Int = 0
Вычисленные свойства не хранят значения. Таким образом, вы не можете присвоить значение вычисляемому свойству. Свойство Computed должно иметь метод получения, который возвращает значение. В широком смысле, вы можете рассматривать вычисляемое свойство как свойство, которое возвращает значение функции.
Пример вычисляемого свойства
var proA: Int {
return proB * proC
}
Что касается ваших вопросов:
- Computed Property - это свойство, которое не хранит значение и содержит метод get для возврата "вычисленного" значения свойства.
- a правильно, b вычисляемые свойства не должны иметь инициализации, c если вы имеете в виду willSet и didSet. Да, они как наблюдатели, когда значение свойства изменится и изменилось соответственно
- Поскольку значение вычисляемого свойства не сохраняется и никогда не будет использовано, компилятор запрещает это.
Надеюсь это немного поможет.
- Интересно, что делает свойство вычисляемым свойством? Верно ли, что если свойство имеет геттер и возвращает его, это вычисленное свойство?
Если вы определите
get { }
внутри объявления свойства оно превращает это свойство в вычисляемое свойство. И он не может иметь начальное значение, так как при доступе к свойству, он всегда будет вызыватьget{}
Функция объявлена в свойстве.
Все ли мои представления (а, б и в) верны? Если не было бы мило с вашей стороны указать
- это правильно
- б неправильно.
Вы не можете установить начальное значение для вычисляемого свойства. Потому что, как я объяснил в вопросе 1, он всегда будет возвращать результат
get{}
когда вам нужен доступ к собственности.- с: 50% верно
сеттер, его также можно использовать как для хранения
newValue
в другую личную переменную, и вы можете сделать некоторые дополнительныеobserving
логика. Таким образом, чтобы наблюдать изменения значения хранимого свойства, вы используетеwillSet
а такжеdidSet
Вы можете определитьobserving
логика вычисляемого свойства (которое имеетgetter
а такжеsetter
) наset{}
декларация. Но главная цельset {}
это сохранить значение в другой переменной или, например,UserDefaults
,Почему нельзя инициализировать вычисляемое свойство? (См. Рисунок ниже). И когда я это делаю, компилятор выдает предупреждение. Невозможно вызвать значение типа non-function "int". Что означает эта ошибка?
Тот же ответ
Ваш код приводит в замешательство компилятор. Когда вы устанавливаете начальное значение для свойства в объявлении, компилятор пытается понять его как
stored
имущество. Но вы также определилиget{}
для этого свойства, а это значит, что это вычисляемое свойство и должно всегда возвращать22
когда вы получаете доступ к собственности. Таким образом, вы должны удалить один из двух.
А. Да, свойство с единственным наблюдателем является сохраненным свойством, а не вычисляемым свойством. Наблюдатель свойства Beacuase отслеживает значение свойства, значение которого было инициализировано ранее и теперь меняется, это сохраненное свойство. Это не применимо для вычисляемого свойства, так как не имеет предопределенного значения
б. Свойство computed - это свойство, значение которого зависит от других переменных. Мы должны объявлять только те свойства как вычисляемое свойство, которое необходимо вычислить с использованием значения других переменных, поэтому его значение нельзя инициализировать заранее. например, - если у нас есть 2 переменные a & b. нам нужно их добавочное значение, поэтому используется переменная с именем 'sum', тогда сумма будет объявлена как вычисляемое свойство, а ее блок get{} вернет (a+b) сумму a & b и значение переменной sum. Тогда в этом случае мы не можем заранее инициализировать свойство 'sum', потому что оно будет вычислено с использованием a & b.
с. Сеттер не является наблюдателем, он устанавливает значение другой переменной или выполняет некоторые действия, связанные с другими переменными, тогда как наблюдатель свойства отслеживает изменения в значении своей связанной переменной. например, бессмысленно использовать наблюдатель свойства для переменной "сумма", как описано в пункте б.