> Все ли нормально с рекурсивно ссылающейся на себя структурой (iOS, Swift)

Уровень: senior · Роль: mobile · Категория: Технические вопросы

Компании: Сбер

Стек: iOS, Swift

> Пример ответа

Короткий ответ

Да, всё нормально, если структура ссылается на себя через reference type (class, closure) или косвенно через indirect enum. Прямая рекурсивная ссылка на value type (struct) невозможна - компилятор выдаст ошибку, потому что размер структуры становится бесконечным. Для этого используется indirect для enum или хранение ссылки на класс внутри структуры.

Подробное объяснение

Проблема в том, что структура - value type, и её память выделяется inline. Если структура содержит поле своего же типа, компилятор не может вычислить её размер: каждая структура содержит ещё одну структуру, та - ещё одну, и так до бесконечности.

SWIFT
struct Node {
let value: Int
let next: Node? // ❌ error: value type 'Node' cannot have a stored property that recursively contains it
}

Решение - сделать ссылку косвенной. Варианты:

  1. Класс внутри структуры - класс это reference type, хранится по ссылке, размер известен (8 байт на 64-битной платформе).
SWIFT
final class NodeBox {
var value: Int
var next: Node?
init(value: Int, next: Node? = nil) { ... }
}
struct Node {
let value: Int
let next: NodeBox?
}
  1. indirect для enum - компилятор автоматически оборачивает рекурсивные case в ссылку.
SWIFT
indirect enum LinkedList<Element> {
case empty
case node(value: Element, next: LinkedList<Element>)
}
  1. Замыкание - замыкание тоже reference type, но это менее удобно для структур данных.

Важно понимать trade-off: структура с ссылкой на класс перестаёт быть чисто value type - копирование структуры копирует ссылку, а не содержимое. Это нарушает семантику копирования, ожидаемую от структур. Если нужна value semantics, лучше использовать indirect enum или пересмотреть дизайн.

На практике

В реальном iOS-коде рекурсивные структуры встречаются редко. Чаще используют классы для деревьев, списков, графов. Если структура нужна для value semantics, indirect enum - самый чистый вариант: он сохраняет копирование по значению на верхнем уровне, а рекурсивные части оборачивает в ссылки автоматически.

Для простых случаев (например, дерево с двумя детьми) можно использовать класс-обёртку, но это добавляет мутабельность и reference semantics. Если структура маленькая и иммутабельная, indirect enum предпочтительнее - он даёт pattern matching и не требует ручного управления ссылками.

Пример кода

SWIFT
// Вариант с indirect enum - сохраняет value semantics на верхнем уровне
indirect enum Tree<Element> {
case leaf(Element)
case node(Tree<Element>, Tree<Element>)
}
// Вариант с классом внутри структуры - проще, но reference semantics
final class BinaryNode<Element> {
var value: Element
var left: BinaryNode<Element>?
var right: BinaryNode<Element>?
init(_ value: Element) { self.value = value }
}
struct BinaryTree<Element> {
var root: BinaryNode<Element>?
}

Как отвечать на собеседовании

Начни с прямого ответа: "Да, но только через reference type или indirect". Объясни причину - бесконечный размер value type. Покажи два-три варианта решения, упомяни trade-off между value и reference semantics. Если спросят про производительность - отметь, что indirect enum добавляет уровень косвенности, но это незначительно. Хорошо добавить пример из практики: дерево, список, граф.

Что проверяет интервьюер

  • Понимание разницы между value и reference type в Swift
  • Знание ограничений структур (inline storage, фиксированный размер)
  • Умение находить обходные пути для рекурсивных структур
  • Понимание последствий для семантики копирования

Типичные ошибки

  • Утверждение, что рекурсивная структура вообще невозможна - это неверно, возможна через ссылку
  • Предложение использовать class вместо структуры без объяснения trade-off
  • Игнорирование indirect для enum - многие забывают, что это ключевое слово существует
  • Непонимание, что копирование структуры с классом внутри копирует только ссылку, а не данные

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью