Видеокурсы по изучению языка программирования Swift. Подробнее

Рекурсивные перечисления

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

Рекурсивное перечисление - перечисление, которое имеет другой экземпляр перечисления в качестве ассоциативного значения для одного или более кейсов перечисления. Чтобы обозначить кейс перечисления в качестве рекурсивного, вам нужно написать indirect до имени перечисления, что сообщит компилятору, что нужно вставить необходимый слой индиректности.

Например, ниже объявлено перечисление, которое хранит простые арифметические выражения:

enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

Вы так же можете написать indirect прямо перед самим перечислением, что позволит обозначить то, что все члены перечисления поддерживают индиректность:

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

Перечисление может хранить три вида арифметических выражений: простое число, сложение двух выражений, умножение двух выражений. Члены addition и multiplication имеют два связанных значения, которые так же являются арифметическими выражениями. Эти связанные значения делают возможным вложение выражений. Например, выражение (5 + 4) * 2 имеет цифру справа от умножения и другое выражение слева от умножения. Поскольку данные вложены, перечисление использующееся для хранения данных, также должно поддерживать вложенность-это означает, что перечисление должно быть рекурсивными. Приведенный ниже код показывает как работает рекурсивное перечисление ArithmeticExpression для (5 + 4) * 2:

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

Рекурсивные функции - самый простой путь работать с данными, которые имеют рекурсивную структуру. Например, ниже приведен пример, как функция вычисляет арифметическое выражение:

func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case let .number(value):
        return value
    case let .addition(left, right):
        return evaluate(left) + evaluate(right)
    case let .multiplication(left, right):
        return evaluate(left) * evaluate(right)
    }
}
 
print(evaluate(product))
// Выведет "18"

Эта функция вычисляет простое число, просто возвращая ассоциативное значение. Она вычисляет сложение или умножение, вычисляя выражение по левую сторону, затем по правую сторону, затем складывает или умножает их.

 

Swift: 
4.0