Ответ
Ключевое слово indirect позволяет enum хранить экземпляр своего же типа в качестве ассоциированного значения, что делает его идеальным для реализации рекурсивных структур данных.
Примеры реализаций:
-
Связный список (Linked List):
indirect enum LinkedList<Element> { case empty case node(Element, LinkedList<Element>) // Рекурсия: узел указывает на следующий узел (или empty) } // Использование: let list: LinkedList<Int> = .node(1, .node(2, .node(3, .empty))) -
Бинарное дерево (Binary Tree):
indirect enum BinaryTree<Element> { case empty case node(Element, BinaryTree<Element>, BinaryTree<Element>) // Левый и правый потомки } // Пример дерева: let tree: BinaryTree<Int> = .node(10, .node(5, .empty, .empty), .node(20, .empty, .empty)) -
Абстрактное синтаксическое дерево (AST) или выражение:
indirect enum ArithmeticExpression { case number(Double) case addition(ArithmeticExpression, ArithmeticExpression) case multiplication(ArithmeticExpression, ArithmeticExpression) } // Выражение: (5 + 2) * 3 let expr: ArithmeticExpression = .multiplication( .addition(.number(5), .number(2)), .number(3) )
Почему indirect? Без него компилятор Swift не может определить фиксированный размер enum, так как он потенциально бесконечен. indirect указывает, что связанное значение хранится по ссылке (в куче), решая эту проблему.