Основы Swift / 11.2. Типы-значения


Видео


Почленные конструкторы для типов-структур
Все структуры имеют автоматически создаваемые почленные конструкторы, которые Вы можете использовать для инициализации свойств-членов новых экземпляров структуры. Начальные значения для свойств нового экземпляра могут быть переданы в почленный конструктор по имени. В отличие от структур экземпляры классов не получают почтенный конструкторов по-умолчанию.
@{11.2\1\1}
struct Resolution {
    var width = 0
    var height = 0
}
let vga = Resolution(width: 640, height: 480)
Структуры и перечисления как типы-значения
Тип-значение - это тип, который копируется при присвоении константе или переменной или при передаче в функцию.

Вы уже фактически использовали типы-значения на протяжении предыдущих глав. Фактически, все базовые типы в Swift - целые числа, дробные числа, Булевы величины, строки, массивы и словари - это типы-значения, которые реализованы в качестве структур за кулисами. Все структуры и перечисления - это типы-значения в Swift. Это означает, что любая структура или перечисление, которые Вы создаёте, а также любые типы, которые они имеют в качестве свойств - всегда копируются, когда передаются в Вашем коде.
@{11.2\1\2}
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
В этом примере объявляется константа под названием hd и устанавливается в экземпляр Resolution, проинициализированный шириной и высотой видео full HD (1920 пикселей в ширину на 1080 пикселей в высоту).

Затем объявляется переменная с названием cinema и устанавливается в текущее значение hd. Так как Resolution - это структура, то происходит её копирование, и уже новая копия присваивается cinema. Хотя даже hd и cinema теперь и имеют одни и те же значения ширины и высоты, на деле это две полностью разных сущности.
@{11.2\1\3}
Далее свойство width у переменной cinema изменяется на супер-широкоформатный стандарт 2K для проекции цифрового кино (2048 пикселей в ширину и 1080 пикселей в высоту).
cinema.width = 2048
@{11.2\1\4}
Проверив свойство width у cinema, мы увидим, что оно действительно изменилось на 2048.
print("cinema теперь имеет \(cinema.width) пикселей в ширину")
// Выводит "cinema теперь имеет 2048 пикселей в ширину"
@{11.2\1\5}
Однако свойство width у оригинального объекта hd всё так же имеет значение 1920.

Когда cinema получают текущее значение hd, то значения, хранимые в hd, копируются в новый объект cinema. Конечный результат будет состоять в двух полностью разных объектах, которые только что хранили одни и те же числовые значения. Так как они являются отдельными объектами, то установка ширины у cinema в 2048 не повлияет на ширину, хранимую в hd.
print("hd всё ещё имеет \(cinema.width) пикселей в ширину")
// Выводит "hd всё ещё имеет 1920 пикселей в ширину"
@{11.2\2}
То же поведение применимо к перечислениям.

Когда rememberedDirection задаётся значение currentDirection, то фактически происходит копирование этого значения. Изменение значения currentDirection позднее не оказывает воздействия на копию оригинального значения, которое хранилось в rememberedDirection.
enum CompassPoint {
    case north, south, east, west
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection = .east
if rememberedDirection == .west {
    print("Запомненное направление всё ещё .west")
}
//Выводит "Запомненное направление всё ещё .west"