[Swift] Enumerations (์—ด๊ฑฐํ˜•)

LEEHAKJIN-VVยท2022๋…„ 5์›” 4์ผ
0

Study-Swift 5.6

๋ชฉ๋ก ๋ณด๊ธฐ
5/22

์ฐธ์กฐ์‚ฌ์ดํŠธ:
The Swift Language Guide
boostcourse


๐ŸŽ Enumerations

  • ์œ ์‚ฌํ•œ(๊ด€๋ จ๋œ)๊ฐ’์„ ํ•œ๊ณณ์— ๋ชจ์•„ ์ •์˜.
  • enum์€ ์™„์ „ ์ƒˆ๋กœ์šด ํ˜•(type)์„ ์ •์˜ํ•˜๋ฏ€๋กœ ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘
  • ๊ฐ case๋Š” ์†Œ๋ฌธ์ž๋กœ ์‹œ์ž‘

๐Ÿ Enumeration ๋ฌธ๋ฒ•

enum ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์—ด๊ฑฐํ˜•์„ ์ •์˜.

enum SomeEnumeration{
    // enumeration definition goes here
}

๋‹ค์Œ์€ 4๊ฐ€์ง€ ๋ฐฉํ–ฅ์„ ๊ฐ–๋Š” CompassPoint ์—ด๊ฑฐํ˜• ์„ ์–ธ์˜ ์˜ˆ์‹œ.

enum CompassPoint{
    case north
    case south
    case east
    case west
}

Swift์—์„œ ์—ด๊ฑฐํ˜•์€ ์ƒ์„ฑ๋  ๋•Œ ์ž๋™์œผ๋กœ ๊ฐ case ๋ณ„๋กœ integer๊ฐ’์ด ํ• ๋‹น ๋˜์ง€ ์•Š๋Š”๋‹ค. (C, Object-C์™€ ์ฐจ์ด์ ) ์œ„ CompassPoint๋ฅผ ๋ณด๋ฉด, ๊ฐ case๋“ค์€ ์•”์‹œ์ ์œผ๋กœ 0,1,2,3๊ฐ’์„ ๊ฐ–์ง€ ์•Š๋Š”๋‹ค. ๋Œ€์‹  ๊ฐ case๋Š” ๊ทธ ์ž์ฒด๋กœ ๊ณ ์œ ์˜ ๊ฐ’์ด๋‹ค.

๋˜ํ•œ ์„ ์–ธ์„ ํ•  ์‹œ ์ฝค๋งˆ(,)๋กœ ๊ตฌ๋ถ„ํ•ด์„œ ํ•œ์ค„์— ์ ์„ ์ˆ˜ ์žˆ๋‹ค.

enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

๊ฐ ์—ด๊ฑฐํ˜•์„ ์ •์˜ํ•œ๋‹ค๋Š” ๋ง์€ ์™„์ „ ์ƒˆ๋กœ์šด ํ˜•์„ ์ •์˜ํ•œ๋‹ค๋Š” ๋ง์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ Swift์˜ ๋‹ค๋ฅธ ํ˜•(types)๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฆ„์€ ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ๋Š” enumeration ์ธ์Šคํ„ด์Šค๋ฅผ ์„ ์–ธํ•˜๋Š” ์˜ˆ์‹œ์ด๋‹ค. ํƒ€์ž…์ถ”๋ก ์„ ํ•˜์ง€ ์•Š๊ณ  ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ณ  ํƒ€์ž…์ถ”๋ก ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

var directionToHead: CompassPoint = CompassPoint.west
//var directionToHead = CompassPoint.west

์ธ์Šคํ„ด์Šค๊ฐ€ ์—ด๊ฑฐํ˜•์œผ๋กœ ํ•œ๋ฒˆ ์ •์˜๊ฐ€ ๋˜๋ฉด ๊ทธ ํ›„๋กœ๋Š” ๊ฐ’์„ ํ• ๋‹นํ•  ๋•Œ ํ˜•์„ ์ƒ๋žตํ•œ ์ถ•์•ฝํ˜• ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ)

directionToHead = .east

๐Ÿ Switch ๊ตฌ๋ฌธ์—์„œ Enumeration ์‚ฌ์šฉ

๊ฐ enumeration ๊ฐ’์„ Switch๋ฌธ์—์„œ ๋งค์นญํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งค์นญ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ Switch๋ฌธ์˜ ๋น„๊ต๊ฐ’์ด ์œ„์น˜ํ•˜๋Š” ์ž๋ฆฌ์— ์—ด๊ฑฐํ˜• ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์œ„์น˜ ์‹œํ‚ค๋ฉด ๋œ๋‹ค.

directionToHead = .south
switch directionToHead {
case .north:
    print("Lots of planets have a north")
case .south:
    print("Watch out for penguins")
case .east:
    print("Where the sun rises")
case .west:
    print("Where the skies are blue")
}
// Prints "Watch out for penguins"

switch๋ฌธ์€ ์—ด๊ฑฐํ˜•์— ์ •์˜๋˜์–ด ์žˆ๋Š” cases๋“ค์„ ๋ฐ˜๋“œ์‹œ ๋ชจ๋‘ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค. ๋งŒ์•ฝ ์œ„์—์„œ case .west ๊ฐ€ ์ƒ๋žต๋˜์—ˆ๋‹ค๋ฉด case๋ฅผ ์ถ”๊ฐ€ํ•˜๋ผ๋Š” ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ฒŒ ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋งŒ์•ฝ ๋ชจ๋“  case๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด default case๋ฅผ ์‚ฌ์šฉํ•˜์ž.

let somePlanet = Planet.earth
switch somePlanet {
case .earth:
    print("Mostly harmless")
default:
    print("Not a safe place for humans")
}

๐ŸŠ Associated Values

์ด์ „ ์„น์…˜์—์„œ๋Š” ์—ด๊ฑฐํ˜•์ด ๊ทธ ์ž์ฒด๋กœ ์ •์˜๋œ ๊ฐ’์ž„์„ ๋ณด์—ฌ์ค€๋‹ค. ๋˜ํ•œ ์ƒ์ˆ˜๋‚˜ ๋ณ€์ˆ˜๋ฅผ Planet.earth๋กœ ์„ค์ •ํ•˜๊ณ  ๋‚˜์„œ ์ดํ›„์— ์ด ๊ฐ’์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋–„๋–„๋กœ๋Š” ์ด๋Ÿฌํ•œ ์ผ€์ด์Šค๋“ค์˜ ๊ฐ’์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ์—ฐ๊ด€ ๊ฐ’(Associated Values)์ด๋ผ๊ณ  ํ•œ๋‹ค.
์ฆ‰ ์—ด๊ฑฐํ˜•์˜ ๊ฐ case์— custom type์˜ ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์œ„ ๋ฐ”์ฝ”๋“œ์™€ ๊ฐ™์ด 4๊ฐ€์ง€์˜ ์ˆซ์ž๋กœ ์ด๋ฃจ์–ด์ง„ ์ข…๋ฅ˜, 2953๊ฐœ์˜ ๋ฌธ์ž๋กœ ๊ตฌ์„ฑ๋œ QR์ฝ”๋“œ ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ง„ ๋‘ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด ๋ฐ”์ฝ”๋“œ ๋ชจ๋‘๋ฅผ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด case๋“ค์˜ customํ•ด์•ผ ํ•˜๋ฏ€๋กœ association values์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด ๋ฐ”์ฝ”๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

์—ฐ๊ด€ ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ (Int, Int, Int, Int)๋ฅผ value๋กœ ๊ฐ–๋Š” upc ๋ฐ”์ฝ”๋“œ์™€ String์„ value๋กœ ๊ฐ–๋Š” qrCode๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
์ด๊ฒƒ์€ ์‹ค์ œ๋กœ Int๋‚˜ String๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ณ€์ˆ˜๊ฐ€ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์œ ํ˜•์„ ์ •์˜ํ•œ ๊ฒƒ์ด๋‹ค.

์ด enumeration์„ ์ด์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด 2๊ฐ€์ง€ ์ข…๋ฅ˜์˜ ์ƒˆ๋กœ์šด ๋ฐ”์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

// Create upc barcode
var productBarcode = Barcode.upc(8, 85909, 51226, 3)

// Create qrCode barcode
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

์ด ์‹œ์ ์—์„œ ๋ณด๋ฉด productBarcode๋ณ€์ˆ˜(์ƒ์ˆ˜)๋Š” .upc or .qrCode์˜ ์œ ํ˜•์˜ type์„ ๋ชจ๋‘ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.(๊ทธ๋Ÿฌ๋‚˜ ๋™์‹œ์—๋Š” ์˜ค์ง 1๊ฐœ๋งŒ ์ €์žฅ ๊ฐ€๋Šฅ)

๐Ÿ‹ Associated Values Switch๋ฌธ ์‚ฌ์šฉ

์œ„์˜ (๐ŸSwitch ๊ตฌ๋ฌธ์—์„œ Enumeration ์‚ฌ์šฉ) switch๋ฌธ๊ณผ ์œ ์‚ฌํ•˜๋‚˜, associated value๊ฐ€ switch๋ฌธ์—์„œ ์ถ”์ถœ๋œ๋‹ค๋Š” ์ ์ด ๋‹ค๋ฅด๋‹ค. switch๋ฌธ ๋‚ด์—์„œ ์ด๋Š” ์ƒ์ˆ˜(let) ๋˜๋Š” ๋ณ€์ˆ˜(var)๋กœ ์ถ”์ถœ๋  ์ˆ˜ ์žˆ๋‹ค.

switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."

์ด๋•Œ case์•ˆ์˜ associated values๊ฐ€ ์ „๋ถ€ ์ƒ์ˆ˜์ด๊ฑฐ๋‚˜ ๋ณ€์ˆ˜์ด๋ฉด ๊ณตํ†ต๋œ ๊ฐ’์„ case ๋’ค์— ์„ ์–ธํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
    print("UPC : \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
    print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."

๐ŸŒ Raw Values

associated value์™€ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ enumeration cases๋“ค์€ ๋™์ผํ•œ ์œ ํ˜•์ธ ์›์‹œ ๊ฐ’(raw value)์„ ๊ฐ€์ง€๊ณ  ๋ฏธ๋ฆฌ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}.

์œ„ ์˜ˆ์‹œ์—์„œ raw value์„ chartercs๋กœ ์ •์˜ํ–ˆ์ง€๋งŒ string, integer, float ํ˜•์œผ๋กœ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ, ๊ฐ raw value์€ ์œ ์ผํ•œ ๊ฐ’์œผ๋กœ ์ค‘๋ณต๋˜์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค.

raw value์™€ associated value์€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค. raw value์€ ์ฝ”๋“œ์—์„œ ์ฒ˜์Œ ์ •์˜๋  ๋•Œ ๊ฐ’์„ ๊ฐ€์ง€๊ณ , ํŠน์ • enumeration case์˜ raw value ํ•ญ์ƒ ๋™์ผํ•˜๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ associated values์€ enumeration's cases ์ค‘์—์„œ ํ•˜๋‚˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์ˆ˜๋‚˜ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค ๋•Œ ๊ฐ’์„ ๊ฐ€์ง€๋ฉฐ ์ด๋Š” ์ƒ์„ฑ ๋•Œ๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค.


๐Ÿ‰ ์•”์‹œ์ ์œผ๋กœ ํ• ๋‹น๋œ Raw Values

์—ด๊ฑฐํ˜•์„ ๋‹ค๋ฃจ๋ฉด์„œ raw value๋กœ Integer๋‚˜ String์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ฐ case ๋ณ„๋กœ ๋ช…์‹œ์ (explicitly)์œผ๋กœ ๊ฐ’์„ ํ• ๋‹นํ•  ํ•„์š”๋Š” ์—†๋‹ค. ๋งŒ์•ฝ ๋ช…์‹œ์ ์œผ๋กœ ํ• ๋‹นํ•˜์ง€ ์•Š์„ ์‹œ, Swift์—์„œ ์ž๋™์œผ๋กœ ๊ฐ’์„ ํ• ๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด raw values๋กœ Integers์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ๊ฐ case์˜ value๋Š” ์•”์‹œ์ ์œผ๋กœ ์ด์ „ ๊ฐ’ ๋ณด๋‹ค 1์”ฉ ์ฆ๊ฐ€ํ•œ๋‹ค. ๋งŒ์•ฝ ์ฒซ ๋ฒˆ์งธ case๊ฐ€ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋ฉด ์ž๋™์œผ๋กœ 0 ๊ฐ’์„ ๊ฐ€์ง„๋‹ค.

enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

์œ„ ๊ฒฝ์šฐ๋Š” ์ฒซ๋ฒˆ์งธ case์ธ mercury์— 1์„ raw value๋กœ ๋ช…์‹œ์ ์œผ๋กœ ํ• ๋‹นํ–ˆ๊ณ , venus๋Š” 2 ๊ทธ๋ฆฌ๊ณ  ์ดํ›„ ๊ฐ’์€ 1์ฆ๊ฐ€ ๋œ ๊ฐ’์„ ์ž๋™์œผ๋กœ raw value๋กœ ๊ฐ€์ง„๋‹ค. ๋งŒ์•ฝ String์„ raw ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด case์˜ name(์ด๋ฆ„)์„ raw value์œผ๋กœ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.

enum CompassPoint: String {
    case north, south, east, west
}

์œ„ ๊ฒฝ์šฐ CompassPoint.south๋Š” ์•”์‹œ์ ์œผ๋กœ "south"๋ฅผ raw value๋กœ ๊ฐ–๋Š”๋‹ค.

enumeration case์˜ raw value์€ rawValue ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

๐Ÿ‡ Raw value๋ฅผ ์ด์šฉํ•œ ์ดˆ๊ธฐํ™”

๋งŒ์•ฝ enumeration์„ raw-value ํƒ€์ž…์œผ๋กœ ์ •์˜ํ•œ๋‹ค๋ฉด, enumeration์€ ์ž๋™์œผ๋กœ rawValue๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๋Š” initializer์„ ๊ฐ€์ง„๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์€ enumeration case ๋˜๋Š” nil์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ฆ‰ raw value์„ ์ด์šฉํ•ด ์—ด๊ฑฐํ˜• ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ๋Š” raw value์ด 7์ธ Uranus์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus

๋ชจ๋“  Int ๊ฐ’๋“ค์ด ๋งž๋Š” planet๋ฅผ ๋ชป ์ฐพ์„ ์ˆ˜๋„ ์žˆ๋‹ค. initializer๋Š” optional enumeration case๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

ํƒ€์ž…์ถ”๋ก ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  initializer๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด Optional ์ธ์Šคํ„ด์Šค์ž„์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ช…์‹œํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

let possiblePlanet: Planet? = Planet(rawValue: 7)

// error
let possiblePlanet: Planet = Planet(rawValue: 7)

raw vlaue initializer๋Š” failable initializer(์‹คํŒจํ•  ์ˆ˜ ์žˆ๋Š” ์ดˆ๊ธฐ์ž)์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ชจ๋“  raw value์— ๋Œ€ํ•ด enmeration case์˜ ๋ฐ˜ํ™˜์ด ๋ณด์žฅ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋งŒ์•ฝ enumeration์— ์ง€์ •๋œ raw value๊ฐ€ ์—†๋Š” ๊ฐ’์œผ๋กœ initializer๋ฅผ ์ง€์ •ํ•˜๋ฉด ๋ฐ˜ํ™˜ ๊ฐ’์€ nil์ด ๋œ๋‹ค.

let positionToFind = 11
if let somePlanet = Planet(rawValue: positionToFind) {
    switch somePlanet {
    case .earth:
        print("Mostly harmless")
    default:
        print("Not a safe place for humans")
    }
} else {
    print("There isn't a planet at position \(positionToFind)")
}
// Prints "There isn't a planet at position 11"

๐Ÿ“ Recursive Enumerations

์žฌ๊ท€ ์—ด๊ฑฐ์ž(recursive enumerations)์€ case ๊ฐ’์œผ๋กœ ๋‹ค๋ฅธ ์—ด๊ฑฐ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ–๋Š” ์—ด๊ฑฐํ˜•์ด๋‹ค. ์žฌ๊ท€ ์—ด๊ฑฐ์ž case ์•ž์—๋Š” indirect ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

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

๋งŒ์•ฝ Association value๋ฅผ ๊ฐ–๋Š” ๋ชจ๋“  ์—ด๊ฑฐํ˜• case์— indirect ํ‘œ์‹œ๋ฅผ ํ•˜๊ณ  ์‹ถ์œผ๋ฉด enum ํ‚ค์›Œ๋“œ ์•ž์— ์‚ฌ์šฉํ•œ๋‹ค.

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

์•„๋ž˜ ์˜ˆ์‹œ๋Š” (5+4) * 2 ๋ฅผ recursive enumerations์œผ๋กœ ํ‘œํ˜„ํ•˜์˜€๋‹ค.

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
print(product)
//Prints "18"

๋‹ค์Œ์€ ์œ„์˜ recursive enumerations์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๊ฐ–๋Š” ํ•จ์ˆ˜์ด๋‹ค.

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"

0๊ฐœ์˜ ๋Œ“๊ธ€