TGViewer
Мобильный трудоголик Мобильный трудоголик @hardworkerit · 1.64K subscribers
Post #217 1.37K
🔢 Структуры и мутабельность: разбираем тонкости let и var.

Всем привет! Сегодня поговорим о, казалось бы, базовой теме: выборе между let и var в структурах Swift. Но, как оказалось, даже здесь есть много тонкостей, которые влияют на поведение нашего кода.

Все мы знаем, что let создает константу, а var переменную. Но в контексте структур есть важные нюансы:


Проблемы с let и опциональными типами.

Когда мы используем let для опциональных свойств, мы обязаны явно передавать значения в инициализаторе, даже если хотим передать nil:


struct User {
let id: UUID
let name: String
let email: String?
}

// Ошибка компиляции: Missing argument for parameter 'email' in call
let user1 = User(
id: UUID(),
name: "Андрей"
)

// Обязаны явно указать nil для свойства email.
let user2 = User(
id: UUID(),
name: "Вася",
email: nil
)


Теперь посмотрим на пример с var:


struct User {
let id: UUID
let name: String
var email: String?
}

// Оба варианта работают:
let user1 = User(
id: UUID(),
name: "Петр"
)

let user2 = User(
id: UUID(),
name: "Иван",
email: nil
)


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


Дефолтные значения и let.

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


// id не будет задаваться в инициализаторе, он всегда будет новым (даже при декодировании из JSON):
struct User {
let id = UUID()
let name: String
}

let user = User(name: "Максим")


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


Кастомные инициализаторы в помощь.

Если нужна читаемост и гибкость, то напишем свой инициализатор:


struct User {
let id: UUID
let name: String
let email: String?

init(
id: UUID = UUID(),
name: String,
email: String? = nil
) {
self.id = id
self.name = name
self.email = email
}
}


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


Property Wrapper для иммутабельности.

Можно создать кастомное решение для read-only свойств с дефолтными значениями:


@propertyWrapper
struct Readonly<Value> {
let wrappedValue: Value
}

struct User {
@Readonly var id = UUID()
var name: String
@Readonly var email: String?
}


Обертка свойства @Readonly имитирует поведение let, но с поддержкой дефолтных значений. Однако этот подход добавляет сложности и может сделать код менее читаемым.


💡 Вывод:

Начинайте с let для всех свойств, это обеспечивает безопасность и предсказуемость. Переходите на var только когда появляется реальная необходимость изменять данные.

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

➡️ Подписаться на канал
Мобильный трудоголик
  • ❤ 13
  • 👍 13
  • 🙏 4
  • 🔥 2
  • 👏 1
  • 👀 1
More from @hardworkerit
  1. Oct 6, 2026🔢 Swift 6.4: новая диагностика ретейн циклов. В Swift 6.4 появилась новая диагностика, ко…
  2. Oct 4, 2026🔢 SwiftUI: определение угла раскрытия iPhone Duo. В iOS 27.1 появился модификатор .onHing…
  3. Oct 2, 2026👣 Архитекторы, тестировщики и кодеры. Создаем мультиагентную команду Разработка с ИИ-аген…
  4. Oct 1, 2026🔢 Работа с Picture-in-Picture в iOS. Picture-in-Picture - системная функция iOS, которая…
  5. Sep 29, 2026🔢 Управление тулбарами на iPhone Duo. На iPhone Duo элементы управления навигацией, дейст…
  6. Sep 27, 2026🔢 Новые возможности Hashable в Swift 6.4 В Swift 6.4 добавили Hashable для нескольких тип…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →