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

Инициализаторы в расширениях

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

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

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

Заметка

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

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

Пример ниже определяет структуру Rect для отображения геометрического прямоугольника. Пример так же определяет две вспомогательные структуры Size и Point, обе из которых предоставляют значения по умолчанию 0.0 для всех своих свойств:

struct Size {
    var width = 0.0, height = 0.0
}
struct Point {
    var x = 0.0, y = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
}

Из-за того, что структура Rect предоставляет значения по умолчанию для всех своих свойств, она автоматически получает инициализатор по умолчанию и почленный инициализатор, что описано в главе Дефолтные инициализаторы. Эти инициализаторы могут быть использованы для создания экземпляров Rect:

let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
                          size: Size(width: 5.0, height: 5.0))

Вы можете расширить структуру Rect для предоставления дополнительного инициализатора, который принимает определенную точку и размер:

extension Rect {
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}

Этот новый инициализатор начинается с вычисления исходной точки, основываясь на значениях свойств center и size. Потом инициализатор вызывает почленный инициализатор структуры init(origin:size:), который хранит новую исходную точку и размеры в соответствующих свойствах:

let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
                      size: Size(width: 3.0, height: 3.0))
// исходная точка centerRect (2.5, 2.5) и его размер (3.0, 3.0)

Заметка

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

 

Swift: 
4.0