열거형 (Enumeration) - 재귀 열거형 (Recursive Enumerations)

00yhsp·2024년 4월 9일

재귀 열거형 (recursive enumeration) 은 열거형 케이스에 하나 이상의 연관된 값으로 열거형의 다른 인스턴스를 가지고 있는 열거형이다. 열거형 케이스가 재귀적임을 나타내기 위해 케이스 작성 전에 indirect 를 작성하여 컴파일러에게 필요한 간접 (indirection) 계층을 삽입하도록 지시한다.

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)
}

이 열거형은 숫자, 2개의 표현식의 덧셈, 2개의 표현식의 곱셈의 3가지의 산술 표현식을 저장할 수 있다.
addition 과 multiplication 케이스는 산술 표현식인 연관된 값을 가지고 있고 이 연관된 값은 중첩 표현식을 가능하게 해준다. 예를 들어 (5 + 4) 2 표현식은 곱셈의 우항은 하나의 숫자를 가지고 있고 좌항은 다른 표현식을 가지고 있다. 데이터는 중첩되기 때문에 데이터를 저장하는 열거형도 중첩을 지원해야 한다. 이것은 열거형은 재귀적이어야 한다는 의미이다. 아래의 코드는 (5 + 4) 2 에 대해 생성되는 ArithmeticExpression 재귀 열거형을 나타낸다:

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))
// Prints "18"

이 함수는 단순하게 관련된 값을 반환하여 숫자를 판단한다. 좌항의 식을 판단하고 우항의 식을 판단한 다음에 이를 더하거나 곱하여 덧셈 또는 곱셈을 판단한다.

profile
iOS Dev

0개의 댓글