Что такое "получить" и "установить" в Swift?
Я изучаю Swift и читаю The Swift Programming Language
от Apple, у меня нет фона Objective C (только PHP, JS и другие, но нет Obj C)
На странице 24-25 я вижу этот код:
//...Class definition stuff...
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
//...Class continues...
Эта часть НЕ указана в книге, и я не могу понять, для чего они.
Может кто-нибудь объяснить мне, что получить и установить?
Ответы
Ответ 1
Это фактически объяснялось прямо перед кодом:
В дополнение к простым сохраненным свойствам свойства могут иметь геттер и сеттер.
class EquilateralTriangle: NamedShape {
...
Когда какой-то другой класс хочет получить эту переменную периметра, они делают это:
let someVar = myTriangle.perimeter
... Что вызывает это:
get{
return 3.0 * self.sideLength
}
И, по сути, это похоже на то, что вызывающий контроллер сделал это:
let someVar = 3.0 * myTriangle.sideLength
Когда вы устанавливаете переменную из другого объекта, она выглядит так:
myTriangle.perimeter = 100
Что вызывает код в блоке set{}
:
set {
sideLength = newValue / 3.0
}
И так, как если бы класс, который установил переменную, сделал это:
myTriangle.sideLength = 100/3.0
Это действительно просто для удобства - вы можете вызывать это из другого кода без необходимости разделить или умножить на 3 все время, потому что это сделано прямо перед установкой переменной и прямо перед тем, как вы получите переменная.
В Swift мы можем иметь свойства, которые вычисляются при получении и могут что-то делать при установке. Мы могли бы сделать это и в Objective-C:
// .h
@property (nonatomic) double perimeter;
//.m
- (double)perimeter
{
return self.sideLength * 3.0;
}
- (void)setPerimeter:(double)perimeter
{
self.perimeter = perimeter; // In Swift, this is done automatically.
self.sideLength = perimeter / 3.0;
}
Ответ 2
Получение и настройка переменных в классах означает либо получение ( "получение" ), либо изменение ( "настройка" ) их содержимого.
Рассмотрим переменную members
для класса family
. Естественно, эта переменная должна быть целым числом, так как семья никогда не может состоять из двух человек.
Итак, вы бы, вероятно, указали переменную members
следующим образом:
class family {
var members:Int
}
Это, однако, даст людям, использующим этот класс, возможность установить количество членов семьи на что-то вроде 0 или 1. И поскольку нет такого понятия, как семейство из 1 или 0, это довольно неудачно.
Здесь появляются геттеры и сеттеры. Таким образом вы можете сами решить, как переменные могут быть изменены и какие значения они могут получить, а также решить, какой контент они вернут.
Возвращаясь к нашему семейному классу, пусть никто не может установить значение members
на что-либо меньшее, чем 2:
class family {
var _members:Int = 2
var members:Int {
get {
return _members
}
set (newVal) {
if newVal >= 2 {
_members = newVal
} else {
println('error: cannot have family with less than 2 members')
}
}
}
}
Теперь мы можем получить доступ к переменной members
, как и прежде, набрав instanceOfFamily.members
, и благодаря функции setter мы также можем установить ее значение как прежде, набрав, например: instanceOfFamily.members = 3
. Однако изменилось то, что мы не можем установить эту переменную на что-либо меньшее, чем 2.
Обратите внимание на введение переменной _members
, которая является фактической переменной для хранения значения, которое мы установили с помощью функции set t members
. Оригинальный members
теперь стал вычисленным свойством, что означает, что он действует только как интерфейс для работы с нашей фактической переменной.
Ответ 3
За простым вопросом должен следовать короткий, простой и понятный ответ.
-
Когда мы получаем значение свойства, он запускает свою часть get{}
.
-
Когда мы устанавливаем значение для свойства, он запускает свою часть set{}
.
PS. При установке значения для свойства SWIFT автоматически создает константу с именем "newValue" = значение, которое мы устанавливаем. После того, как константа "newValue" станет доступной в части свойств set{}
.
Пример:
var A:Int = 0
var B:Int = 0
var C:Int {
get {return 1}
set {print("Recived new value", newValue, " and stored into 'B' ")
B = newValue
}
}
//When we are getting a value of C it fires get{} part of C property
A = C
A //Now A = 1
//When we are setting a value to C it fires set{} part of C property
C = 2
B //Now B = 2
Ответ 4
Вы должны посмотреть Вычислимые свойства
В вашем примере кода perimeter
- это свойство, не подкрепленное переменной класса, вместо этого его значение вычисляется с использованием метода get
и сохраняется через метод set
, обычно называемый getter и setter.
Когда вы используете это свойство следующим образом:
var cp = myClass.perimeter
вы вызываете код, содержащийся в блоке кода get
, и когда вы его используете следующим образом:
myClass.perimeter = 5.0
вы вызываете код, содержащийся в блоке кода set
, где newValue
автоматически заполняется значением, указанным справа от оператора присваивания.
Вычислимые свойства могут быть прочитаны, если указаны как геттер, так и сеттер, или только для чтения, если указан только геттер.