본문 바로가기

Swift Language

Swift Language - 7 - 열거형 (Enumerations)

열거형 문법 (Enumeration Syntax)

// enum키워드를 사용해 열거형을 정의합니다.
enum SomeEnumeration {
    // enumeration definition goes here
}


// 다음은 네 가지 방향을 갖는 CompassPoint 열거형 선언의 (예)입니다.
enum CompassPoint {
    case north
    case south
    case east
    case west
}


// 여러 case를 콤마(,)로 구분해서 한줄에 적을 수 있습니다.
enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}


// 각 열거형 정의는 완전 새로운 타입을 정의합니다.
var directionToHead = CompassPoint.west


/* directionToHead의 형은 초기화 될 때 타입추론이 돼서 CompassPoint형을 갖게 됩니다. 
directionToHead의 형이 CompassPoint로 한번 정의되면 다음에 값을 할당할 때 
형을 생략한 점 문법(dot syntax)을 이용해 값을 할당하는 축약형 문법을 사용할 수 있습니다. */
directionToHead = .east

 

Switch 구문에서 열거형 값 매칭하기 (Matching Enumeration Values with a Switch Statement)

// 각 열거형 값을 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가 생략되었다면 코드는 컴파일 되지 않습니다. 
만약 열거형의 모든 cases의 처리를 기술하는게 적당하지 않다면 
기본(default) case를 제공함으로써 처리되지 않는 case를 피할 수 있습니다. */
let somePlanet = Planet.earth
switch somePlanet {
case .earth:
    print("Mostly harmless")
default:
    print("Not a safe place for humans")
}

 

관련 값 (Associated Values)

// 열거형의 각 case에 custom type의 추가적인 정보를 저장할 수 있습니다.

/* 예를 들어 바코드가 4가지 구분으로 이루어진 숫자로 이루어진 종류가 있거나, 
2,953개의 문자로 구성된 QR코드 형태로 이루어진 두 가지 종류가 있다면 
이 바코드를 아래와 같은 열거형으로 정의할 수 있습니다. */
enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}


// 관련 값을 이용하면 위와 같이 같은 형이지만, 다른 형태의 값을 갖는 case를 만들 수 있습니다. 
// 바코드는 아래와 같이 선언할 수 있고
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
// 이렇게 선언하는 것도 가능합니다.
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")


// 관련 값은 switch case문에서 사용할 때 상수 혹은 변수로 선언할 수 있습니다.
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."


// 공통된 let을 앞으로 빼내 간결하게 기술한 코드
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 값 (Raw Values)

// case에 raw 값을 지정할 수 있습니다.
enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}

 

암시적으로 할당된 Raw 값 (Implicitly Assigned Raw Values)

/* 열거형을 다루면서 raw값으로 Integer나 String 값을 사용할 수 있는데, 
각 case별로 명시적으로 raw값을 할당할 필요는 없습니다. 
만약 raw값을 할당하지 않으면 Swift에서 자동으로 값을 할당해 줍니다. */


/* 아래 경우는 mercury에 1을 raw 값으로 명시적으로 할당했고 
venus는 암시적으로 2 그리고 이후 값은 1증가 된 값을 자동으로 raw값으로 갖게 됩니다. 
만약 String을 raw값으로 사용한다면 case텍스트가 raw값으로 자동으로 raw값으로 할당됩니다. */
enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}


// 아래 경우 CompassPoint.south는 암시적으로 "south"를 raw값으로 갖습니다.
enum CompassPoint: String {
    case north, south, east, west
}


// raw값은 rawValue 프로퍼티를 사용해 접근할 수 있습니다.
let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3

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

 

Raw 값을 이용한 초기화 (Initializing from a Raw Value)

// raw값을 이용해 열거형 변수를 초기화 할 수 있습니다. 

// 아래 예제는 raw값 7을 갖는 값을 열거형 변수의 초기 값으로 지정합니다. 그 값은 Uranus입니다.
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus


// 만약 열거형에 지정된 raw값이 없는 값으로 초기자를 지정하면 그 값은 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)

// 재귀 열거자는 다른 열거 인스턴스를 관계 값으로 갖는 열거형입니다. 

// 재귀 열거자 case는 앞에 indirect키워드를 붙여 표시합니다.
enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}


// 만약 관계 값을 갖는 모든 열거형 case에 indirect표시를 하고 싶으면 enum키워드 앞에 indirect표시를 하면 됩니다.
indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, 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))
// Prints "18"

 

 

 

출처 https://jusung.gitbook.io/the-swift-language-guide/language-guide/08-enumerations