오늘은 야곰님의 Swift 프로그래밍 책을 보며 처음 보는 열거형이 있어서 정리하는 글을 작성하려고 한다.
1. 순환 열거형 이란?
순환 열거형은 열거형 케이스의 연관 값이 열거형 자신의 값이고자 할 때 사용합니다.
재귀적으로 해당 열거형 케이스를 반복하게 되므로 `indirect` 키워드를 사용하여 명시하도록 한다.
Swift에서 열거형은 n개의 case를 생성할 수 있고 그 case는 연관 값(parameter)를 가질 수 있다는 건 알고 있을 것이다.
위 말을 풀어보면 case의 parmeter로 `자기 자신`이 사용된다는 의미이다.
텍스트만 보면 이해가 잘 안될 수도 있는데(내가 그랬음) 예제를 하나하나 뜯어보면 쉽게 알 수 있다.
2. 예제
다음은 간단한 산술 표현식을 저장하는 열거형이다.
이 열거형은 숫자, 2개의 표현식의 덧셈, 2개의 표현식의 곱셈의 3가지의 산술 표현식을 저장할 수 있다.
2-1. 열거형
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
위 예제의 경우, indirect
키워드를 `addition` `multiplication` case 앞에 명시하여 두 case만 한정해 순환 열거형을 만든 것이다.
열거형 연관 값이 자기 자신(ArithmeticExpression)이기 때문에 indirect
키워드를 사용해 순환 열거형으로 만들 수 있다.
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
위 예제의 경우엔 indirect
키워드를 enum 앞에 명시하여 ArithmeticExpression 열거형 전체를 순환 열거형으로 만들었다는 차이가 있다.
2-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))
// Prints "18"
ArithmeticExpression 열거형을 사용해 (5 + 4) X 2
연산을 계산하는 예제입니다.
- `five` 열거형에서 사용될 정수 '5'
- `four` 열거형에서 사용될 정수 '4'
- `sum` addition case로 만든 덧셈 표현식 → (5 + 4)에 해당하는 좌항
- `product` multiplication case로 만든 곱셉 표현식 → sum * 2에 해당하는 우항
- `evaluate` 순환 열거형의 계산을 도와주는 순환 함수
2-3. 전체 코드
더보기
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, 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"