Вычисляемое свойство – это свойство, которое вычисляет и возвращает значение, а не просто его хранит. В этом руководстве мы обсудим, как работают вычисляемые свойства и как их можно использовать в программировании на Swift.
Что такое вычисляемое свойство?
Прежде чем мы начнем обсуждать вычисляемые свойства, давайте для начала сделаем краткий обзор свойств:
- Свойство связано с именем переменной или константы и является частью класса, структуры или перечисления.
- Хранимые свойства представляют простейшую форму хранения значений в виде констант или переменных. Они имеют значение по умолчанию или получают его с помощью инициализатора.
Вычисляемое свойство вычисляет значение, а не хранит его. Вот пример:
struct Rectangle { var width: Double var height: Double var area: Double { width * height } }
В приведенном выше коде мы создали структуру Rectangle. Она имеет два хранимых свойства width и height типа Double. Третье свойство является вычисляемым. Оно выполняет код width * height и возвращает полученное значение при вызове.
let square = Rectangle(width: 12.0, height: 12.0) print(square.area) // 144.0
В приведенном выше коде мы определили квадрат с шириной и высотой 12. Затем мы вычисляем площадь квадрата и выводим полученный результат в консоль.
Вычисляемые свойства похожи на функцию, однако они отличаются. Они имеют лаконичный синтаксис и при правильном использовании сделают ваш код более выразительным и понятным.
Геттеры и сеттеры для вычисляемых свойств
Вычисляемые свойства могут также могут использовать геттер (get) и сеттер (set):
- Геттер выполняется при получении значения свойства.
- Сеттер выполняется при установке нового значения свойства.
struct User { private var firstName = "" private var lastName = "" var name: String { get { return firstName + " " + lastName } set(newValue) { let split = newValue.components(separatedBy: " ") firstName = split[0] lastName = split[1] print("firstName = \(firstName), lastName = \(lastName)") } } } var user = User() user.name = "John Doe" // firstName = John, lastName = Doe print(user.name) // John Doe
В приведенном выше примере мы создали структуру User с двумя хранимыми свойствами firstName и lastName типа String. Третье свойство name вычисляемое.
Для вычисляемого свойства name определены методы get и метод set. Вот их синтаксис:
var property: Type { get { code } set(value) { code } }
Мы можем указать, что должно произойти, когда свойство будет читаться или изменяться. В геттере вы должны вернуть значение. В сеттере вы должны сохранить или изменить какое-либо значение.
Мы можем использовать локальную константу newValue в качестве нового значения, поэтому у нас есть доступ как к новым, так и к текущим значениям. Константа newValue доступна внутри сеттера, поэтому вам не нужно объявлять ее явно. Вы можете, однако, указать собственное имя, если хотите.
set { // newValue - имя по умолчанию } set(newString) { // newString - созданное нами имя }
Вычисляемые свойства только для чтения
Вычисляемое свойство только для чтения может только быть прочитано, но не изменено.
struct Circle { var radius: Double var circumference: Double { 2 * .pi * radius } }
В приведенном выше коде мы определили структуру Circle, которая имеет хранимое свойство radius и вычисляемое свойство только для чтения circumference, оба типа Double.
let earth = Circle(radius: 6371) print(earth.circumference) // 40030.173592041145
Свойство circumference доступно только для чтения – оно имеет только геттер. То есть данный код аналогичен следующему:
var circumference: Double { get { return 2 * .pi * radius } }
Сравнивая его с предыдущим примерами кода, мы видим два отличия:
- Объявление геттера удаляется. Swift понимает, что мы объявляем вычисляемое свойство только для чтения.
- У нас отсутствует return. Начиная с Swift 5.1 однострочные выражения могут опускать return для краткости кода.
Как можно использовать вычисляемые свойства?
Давайте посмотрим на несколько примеров использования вычисляемых свойств.
Во-первых, вычисляемое свойство только для чтения идеально подходит для краткого выражения простых вычисляемых значений. К примеру, можно вычислить окружность круга. Или вы можете получить отформатированный адрес через полученные значения.
struct Person { var street: String var streetNumber: String var city: String var postcode: String var address: String { "\(street) \(streetNumber)\n\(postcode), \(city)" } } let bob = Person(···) print(bob.address) // Output: Московская улица, 23, 2200332, Москва
Вам не нужно хранить полный адрес, только отдельные его компоненты. Вы можете представить их так, как хотите.
Вы также можете использовать методы получения и установки вычисляемых свойств для настройки других значений, кроме самого свойства.
struct RentalCar { var costPerDay: Double var costPerWeek: Double { get { costPerDay * 7.0 } set { costPerDay = newValue / 7.0 } } } var toyota = RentalCar(costPerDay: 12.0) toyota.costPerWeek = 100.0 print(toyota.costPerDay) // 14.28
В приведенном выше коде мы создаем структуру RentalCar которая имеет два свойства:
- Хранимое свойство costPerDay типа Double.
- Вычисляемое свойство costPerWeek типа Double.
Мы можем сказать, что стоимость аренды в неделю – это стоимость в день, умноженная на 7, и наоборот. В приведенном выше кодеcostPerDay является определяющим фактором для аренды автомобиля на любой срок.
Когда costPerWeek будет установлен, мы делим его на 7 и устанавливает в costPerDay. Когда мы получаем значение costPerWeek, мы умножаем его на 7 , чтобы получить стоимость за неделю.
Теперь вы можете работать с как с днями недели, так и с неделями благодаря вычисляемым свойствам. При этом ваш код будет более кратким и легким для чтения.