ГлавнаяБлогСтруктуры в Swift: создаём свои типы данных
Алгоритмы

Структуры в Swift: создаём свои типы данных

Узнайте, как создавать собственные типы данных с помощью структур в Swift. Практические примеры, свойства, методы и мутирующие функции для разработчиков.

Al
Редакция Algolitalgolit.ru
10 мин чтения27 июня 2026 г.

Что такое структуры и зачем они нужны?

В Swift мы привыкли работать со встроенными типами: String, Int, Bool, Array. Но что делать, если нужно описать, например, персонажа аниме или гильдию? Для этого существуют структуры. Структура — это пользовательский тип данных, который может содержать собственные переменные (свойства) и функции (методы). В этой статье вы научитесь создавать структуры, работать с их экземплярами и поймёте, когда их использовать.

Создаём первую структуру

Вот простой пример структуры, описывающей персонажа аниме:

struct AnimeCharacter {
    let name: String
    let show: String
    let powerLevel: Int

    func printSummary() {
        print("\(name) из \(show) — уровень силы: \(powerLevel)")
    }
}

Обратите внимание: AnimeCharacter начинается с заглавной буквы — это соглашение для всех типов в Swift. name, show и powerLevel — это свойства, а printSummary()метод.

Теперь создадим несколько персонажей:

let naruto = AnimeCharacter(name: "Naruto", show: "Naruto Shippuden", powerLevel: 9000)
let goku = AnimeCharacter(name: "Goku", show: "Dragon Ball Z", powerLevel: 9001)

print(naruto.name)      // "Naruto"
print(goku.powerLevel)  // 9001
naruto.printSummary()   // "Naruto из Naruto Shippuden — уровень силы: 9000"
goku.printSummary()     // "Goku из Dragon Ball Z — уровень силы: 9001"

Хотя оба созданы из одной структуры, это разные экземпляры — изменение одного не влияет на другой. Когда вызывается printSummary() у naruto, он использует данные Наруто, а у goku — данные Гоку. Swift обрабатывает это автоматически.

Свойства, методы и экземпляры — словарь терминов

Теперь, когда вы увидели структуру в деле, дадим названия её частям:

  • Свойства — переменные и константы внутри структуры (name, show, powerLevel)
  • Методы — функции внутри структуры (printSummary)
  • Экземпляр — конкретная копия структуры (naruto, goku)
  • Инициализатор — специальная функция для создания экземпляра (AnimeCharacter(name:show:powerLevel:))

Последний пункт стоит рассмотреть подробнее.

Как работают инициализаторы

Когда вы пишете AnimeCharacter(name: "Naruto", show: "Naruto Shippuden", powerLevel: 9000), это похоже на вызов функции. Swift автоматически создаёт внутри каждой структуры специальную функцию init(), используя все свойства как параметры. Эти строки идентичны:

let naruto = AnimeCharacter(name: "Naruto", show: "Naruto Shippuden", powerLevel: 9000)
let naruto = AnimeCharacter.init(name: "Naruto", show: "Naruto Shippuden", powerLevel: 9000)

Обычно используется первый вариант, но теперь вы знаете, что происходит «под капотом».

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

struct Ninja {
    let name: String
    var chakraLevel = 100
}

let kakashi = Ninja(name: "Kakashi")           // chakraLevel = 100 по умолчанию
let rock = Ninja(name: "Rock Lee", chakraLevel: 0)  // у Rock Lee нет чакры 😄

Изменяемые свойства: ключевое слово mutating

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

struct Ninja {
    let name: String
    var chakraLevel: Int

    func train() {
        chakraLevel += 50  // ❌ Не сработает!
        print("\(name) усердно тренировался!")
    }
}

Swift откажется компилировать этот код. Почему? Хотя chakraLevel — переменная, Swift не знает, является ли сам экземпляр структурой переменной (var) или константой (let). Если бы вы создали let ninja, изменение его свойств было бы недопустимо.

Решение — пометить метод, изменяющий свойства, ключевым словом mutating:

struct Ninja {
    let name: String
    var chakraLevel: Int

    mutating func train() {
        chakraLevel += 50
        print("\(name) усердно тренировался! Уровень чакры теперь \(chakraLevel).")
    }
}

Теперь код работает, но только если экземпляр создан как var:

var naruto = Ninja(name: "Naruto", chakraLevel: 100)
naruto.train()  // ✅ "Naruto усердно тренировался! Уровень чакры теперь 150."

let sasuke = Ninja(name: "Sasuke", chakraLevel: 100)
sasuke.train()  // ❌ Ошибка — нельзя вызвать mutating метод у константы

Два важных момента о mutating:

  • Swift верит вам на слово — если метод помечен как mutating, его нельзя вызвать у константы, даже если метод ничего не меняет
  • Неизменяемый метод не может вызывать изменяемый — если нужно, помечайте оба как mutating

Методы vs функции — в чём разница?

Вы можете спросить: если метод — это просто функция внутри структуры, зачем их использовать? Не проще ли обойтись обычными функциями?

Ключевое отличие: методы принадлежат типу — они живут внутри структуры (или класса, или перечисления). Обычные функции существуют сами по себе.

Это важно по двум причинам:

  1. Методы имеют доступ к свойствам структуры:
    struct Guild {
        let name: String
        var memberCount: Int
    
        func describe() {
            // Можно напрямую обращаться к name и memberCount
            print("\(name) насчитывает \(memberCount) участников.")
        }
    }
    Обычная функция вне структуры не смогла бы получить доступ к этим свойствам без явной передачи данных.
  2. Методы избегают загрязнения пространства имён: представьте, что у вас 100 функций: attack(), defend(), heal() — эти имена теперь заняты во всей программе, и может возникнуть конфликт с другими частями кода. Но если это методы структуры Character, то character.attack() однозначно относится к атаке персонажа, а item.attack() может означать совсем другое для структуры Item.

Структуры vs кортежи — что выбрать?

Вы помните кортежи из статьи о функциях — они позволяют вернуть несколько значений за раз:

func getCharacterInfo() -> (name: String, powerLevel: Int) {
    return ("Luffy", 8500)
}

Кортеж и структура могут содержать похожие данные. Когда что использовать?

Кортеж — это анонимная структура. Он хорош для одноразовых ситуаций, например, возврата двух значений из функции. Но если одна и та же форма данных используется в нескольких функциях, лучше выбрать структуру:

// С кортежами — повторяемо и сложно обновлять:
func authenticate(_ user: (name: String, powerLevel: Int, guild: String)) { ... }
func showProfile(for user: (name: String, powerLevel: Int, guild: String)) { ... }
func signOut(_ user: (name: String, powerLevel: Int, guild: String)) { ... }

// Со структурой — чисто, переиспользуемо и легко обновлять:
struct Hero {
    var name: String
    var powerLevel: Int
    var guild: String
}

func authenticate(_ hero: Hero) { ... }
func showProfile(for hero: Hero) { ... }
func signOut(_ hero: Hero) { ... }

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

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

Итоги

ТерминЗначение
СтруктураПользовательский тип данных со своими свойствами и методами
СвойствоПеременная или константа, принадлежащая структуре
МетодФункция, принадлежащая структуре
ЭкземплярКонкретная копия структуры
ИнициализаторФункция для создания экземпляра
mutatingПомечает метод, изменяющий свойства структуры

Структуры — один из важнейших строительных блоков в Swift. В SwiftUI почти всё, что вы будете строить, будет структурой. Освоив их сейчас, вы сделаете дальнейшее обучение намного проще и естественнее. 🌸

Практический вывод

Прямо сейчас откройте Xcode или Swift Playgrounds и создайте структуру для вашего любимого персонажа или объекта. Добавьте 3–5 свойств, напишите метод, который выводит информацию, и поэкспериментируйте с mutating. Чем больше практики — тем быстрее вы освоите Swift.

#структуры Swift#свойства и методы#mutating#инициализаторы#типы данных
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →