공부/SWIFT

[SWIFT] 열거형 (enum)

알로하리미 2021. 3. 9. 16:02
728x90

1. 개요

- 연관된 항목들을 묶어서 표현할 수 있는 타입

- 프로그래머가 정의해준 항목 값 외에는 추가/수정이 불가

- 제한된 선택지를 주고 싶을 때, 정해진 값 외에는 입력받고 싶지 않을 때, 예상된 입력 값이 한정되어 있을 때 사용

- 스위프트의 열거형은 각 열거형이 고유의 타입으로 인정되기 때문에 실수로 버그가 일어날 가능성을 원천 봉쇄할 수 있습니다.

- 열거형은 switch구문과 만났을때 활용이 좋다.

* 옵셔널(Optional)은 enum(열거형)으로 구성되어있다.

 

 

2. 선언

enum으로 선언 할 수 있다. 원시값을 가질 수 있다.

// 열거명:타입 <-- 원시값 타입 설정
enum School: String { 
   case primary = "유치원"
   case elmentary = "초등학교"
   case middle = "중학교"
   case high // 원시값이 설정되지 않으면 항목명이 원시값이 된다. 
}

// 여러 케이스가 쉼표로 구분 된 한 줄에 나타날 수 있습니다
enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}


// 원시값이 정수 타입이고 각 항목에 할당되지 않으면 
// 0부터 1씩늘어난 값이 원시값으로 들어간다.
enum Nubmers: Int{
    case zero
    case one
    case two
    case ten = 10
}

print(Numbers.zero.rawValue) // 0
print(Numbers.one.rawValue)  // 1 
print(Numbers.ten.rawValue)  // 10

// 원시값을 통한 열거형 초기화
let one = Numbers(rawValue: 1) //one
let three = Numbers(rawValue: 3) //없으면 nil 
let ten = Numbers(rawValue: 10) //ten

 

 

3. 연관 값

열거형의 각 항목들은 연관 값을 가질 수 있다.

예를 들어 재고 추적 시스템에서 두 가지 유형의 바코드로 제품을 추적해야한다고 가정 해 보겠습니다. 일부 제품에는 숫자 0 사용하는 UPC 형식의 1D 바코드  9있습니다. 각 바코드에는 숫자 체계 숫자가 있고 그 뒤에 5 개의 제조업체 코드 숫자와 5 개의 제품 코드 숫자가 있습니다. 다음에는 코드가 올바르게 스캔되었는지 확인하기위한 검사 숫자가 있습니다.

다른 제품에는 ISO 8859-1 문자를 사용할 수 있고 최대 2,953 자 길이의 문자열을 인코딩 할 수있는 QR 코드 형식의 2D 바코드가 표시되어 있습니다.

재고 추적 시스템은 UPC 바코드를 4 개의 정수로 된 튜플로 저장하고 QR 코드 바코드를 모든 길이의 문자열로 저장하는 것이 편리합니다.

Swift에서 두 유형의 제품 바코드를 정의하는 열거 형은 다음과 같습니다.

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

다음과 같이 읽을 수 있습니다.

"라는 열거 형 정의 Barcode의 값 중 하나를 취할 수있는 upc형태의 관련 값 (와 Int, Int, Int, Int) 또는 값 qrCode유형에 연관된 값 String."을

이 정의는 실제 Int또는 String값을 제공하지 않습니다. 단지 상수와 변수가 또는 같을 때 저장할 수있는 관련 값  유형  정의 할뿐입니다 .BarcodeBarcode.upcBarcode.qrCode

그런 다음 두 유형 중 하나를 사용하여 새 바코드를 만들 수 있습니다.

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

이 예제에서는라는 새 변수를 만들고 연결된 튜플 값이 인 productBarcode값을 할당합니다 .Barcode.upc(8, 85909, 51226, 3)

동일한 제품에 다른 유형의 바코드를 할당 할 수 있습니다.

productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

이 시점에서 원래 Barcode.upc값과 정수 값은 새 Barcode.qrCode값과 문자열 값으로 대체됩니다 . 유형의 상수 및 변수는 Barcodea .upc또는 a .qrCode(관련 값과 함께)를 저장할 수 있지만 주어진 시간에 둘 중 하나만 저장할 수 있습니다.

Switch 문을 사용하여 열거 형 값 일치 의 예와 유사한 switch 문을 사용하여 다양한 바코드 유형을 확인할 수 있습니다 . 그러나 이번에는 관련 값이 switch 문의 일부로 추출됩니다. 케이스 본문 내에서 사용할 상수 ( let접두사 포함) 또는 변수 (접두사 포함) 로 연결된 각 값을 추출합니다

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."

열거 형 케이스의 모든 관련 값이 상수로 추출되거나 모두 변수로 추출 된 경우 간결성을 위해 케이스 이름 앞에 단일 var또는 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."

 

 

4. 열거형의 재귀(순환 열거형)

순환 열거형은 열거형 항목의 연관 값이 열거형 자신의 값이고자 할때 사용. 순환 열거형을 명시하고 싶다면 indirect 키워드 명시

예를 들어 다음은 간단한 산술 표현식을 저장하는 열거형.

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

또한 열거형 전체에 순환 열거형 명시

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

이 열거는 세 가지 종류의 산술 식을 저장할 수 있습니다 : 일반 숫자, 더하기, 곱하기.  예를 들어, 표현식은 곱셈의 오른쪽에 숫자가 있고 곱셈의 왼쪽에 다른 표현식이 있습니다. 데이터가 중첩되기 때문에 데이터를 저장하는 데 사용되는 열거 형도 중첩을 지원해야합니다. 즉, 열거 형이 재귀적이어야합니다. 아래 코드는 다음에 대해 생성되는 재귀 열거를 보여줍니다 .(5 + 4) * 

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"

이 함수는 단순히 관련 값을 반환하여 일반 숫자를 평가합니다. 왼쪽의 식을 평가하고 오른쪽의 식을 평가 한 다음이를 더하거나 곱하여 더하기 또는 곱하기를 평가합니다.