Видеокурсы по изучению языка программирования Swift. Подробнее

Вычисляемые свойства

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

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

struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 0.0, height = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
    }
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
                  size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// Выведет "square.origin is now at (10.0, 10.0)"

Этот пример определяет три структуры для работы с геометрическими фигурами:

  • Point инкапсулирует координаты (x, y).
  • Size инкапсулирует width, height.
  • Rect определяет прямоугольник по начальной точке и размеру.

Структура Rect так же обеспечивает нас вычисляемым свойством center. Текущий центр Rect может быть определен из origin и size, так что вам не нужно хранить точку центра как явное значение Point. Вместо этого Rect объявляет пользовательский геттер и сеттер для вычисляемой переменной называемой center, для того чтобы была возможность работать с center прямоугольника, как если бы она была обычным свойством хранения.

Предшествующий пример создает новую переменную square типа Rect. Переменная square инициализирована с начальной точкой (0, 0), с высотой и шириной равными 10. Этот квадрат представлен на диаграмме голубым цветом.

Свойство center переменной square доступно тогда, когда мы используем точечный синтаксис (square.center), что вызывает геттер для center, для получения текущего значения свойства. Вместо того, чтобы возвращать существующее значение, геттер считает текущее значение и возвращает новую Point, показывающую центр квадрата. Как вы можете видеть выше, геттер корректно возвращает точку центра как (5, 5).

Потом свойство center устанавливает значение (15, 15), что передвигает квадрат вверх и вправо, на новую позицию, как показано на диаграмме оранжевым квадратом. Установка свойства center вызывает сеттер для center, что обновляет значения x, y свойства origin и двигает квадрат на новую позицию.

Сокращенный вариант объявления сеттера

Если сеттер высчитываемого свойства не определяет имени для нового значения, то используется имя по умолчанию newValue. Альтернативный вариант структуры Rect, обладающей преимуществом сокращенного синтаксиса:

struct AlternativeRect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set {
            origin.x = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
    }
}

Вычисляемые свойства только для чтения

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

Заметка

Вы должны объявлять вычисляемые свойства, включая вычисляемые свойства для чтения, как переменные свойства с ключевым словом var, потому что их значение не фиксировано. Ключевое слово let используется только для константных свойств, значение которых не может меняться, после того как было установлено как часть инициализации экземпляра.

Вы можете упростить объявление вычисляемых свойств только для чтения, удаляя ключевое слово get и его скобки:

struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// Выведет "the volume of fourByFiveByTwo is 40.0"

Этот пример объявляет новую структуру Cuboid, которая представляет 3D прямоугольную коробку с width, height, depth свойствами. Так же эта структура имеет свойство доступное только для чтения volume, которое считает и возвращает текущий объем кубойда. Никакого смысла делать volume значением установленным, так как будет не понятно какие значения width, height и depth должны быть использованы для конкретного значения объема. Тем не менее для кубойда полезно иметь вычисляемое свойство только для чтения, чтобы пользователи могли узнать текущий посчитанный объем.

 

Swift: 
4.0