열거형 (Enumerations)
관련된 값으로 이루어진 그룹을 공통의 형으로 선언하는 것.
열거형 문법 (Enumeration Syntax)
enum 키워드를 사용해 열거형을 정의한다. 스위프트의 다른 형과 마찬가지로 형의 이름은 대문자로 시작해야 한다.
enum SomeEnumeration {
// enumeration definition goes here
}
enum Food {
case krFood
case jpFood
case cnFood
}
✔️ 위의 예제와 같이 스위프트에서 열거형은 생성될 때 각 case 별로 기본 값을 할당하지 않는다.
enum Food {
case krFood, jpFood, cnFood
}
✔️ 위의 예제와 같이 여러 case를 콤마(,)로 구분해서 한줄에 적을 수 있다.
var kimch = Food.krFood
✔️ 위의 예제와 같이 각 열거형 정의는 완전 새로운 형을 정의한다.
enum Food {
case krFood, jpFood, cnFood
}
var ramen = Food.krFood
ramen = .jpFood
✔️ 위의 예제와 같이 한번 초기화 된 변수는 다음에 값을 할당할 때 형을 생략한 점 문법을 이용해 값을 할당하는 축약형 문법을 사용할 수 있다.
enum Food {
case krFood, jpFood, cnFood
}
var food1: Food = .krFood
var food2: Food = .jpFood
var food3: Food = .cnFood
✔️ 위의 예제와 같이 변수에 열거형 타입을 선언하여 점 문법을 이용해 값을 할당할 수 있다.
Switch 구문에서 열거형 값 매칭하기 (Matching Enumeration Values with a Switch Statement)
enum Food {
case krFood, jpFood, cnFood
}
var food1: Food = .krFood
switch food1 {
case .krFood:
print("korean Food!🍚")
case .jpFood:
print("japan Food!🍜")
case .cnFood:
print("china Food!🥠")
default:
print("etc. Food!🍝")
}
// korean Food!🍚
✔️ switch문은 반드시 열거형의 모든 경우(case)를 완전히 포함해야 한다. 만약 위에서 case .cnFood가 생략되었다면 코드는 컴파일 되지 않는다.
enum Food {
case krFood, jpFood, cnFood
}
var food1: Food = .krFood
switch food1 {
case .cnFood:
print("china Food!🥠")
default:
print("etc. Food!🍝")
}
// etc. Food!🍝
✔️ 위의 예제와 같이 만약 열거형의 모든 경우의 처리를 기술하는게 적당하지 않다면 default case를 제공함으로써 처리되지 않는 case를 피할 수 있다.
관련 값 (Associated Values)
열거형의 각 case에 custom type의 추가적인 정보를 저장할 수 있다.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode: Barcode = .upc(1, 2345, 6789, 10)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
✔️ 위의 예제와 같이 관련 값을 이용하면 같은 형이지만, 다른 형태의 값을 갖는 case를 만들 수 있다.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode: Barcode = .qrCode("ABCDEFGHIJKLMNOP")
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).")
}
✔️ 위의 예제와 같이 관련 값은 switch 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."
✔️ 위의 예제와 같이 case 안의 관련 값이 전부 상수이거나 변수이면 공통된 값을 case 뒤에 선언해서 보다 간결하게 기술할 수 있다.
Raw 값 (Raw Values)
enum Capital:String {
case korea = "Seoul"
case japan = "Tokyo"
case china = "Beijing"
case mongol = "Ulaanbaatar"
}
✔️ 위의 예제처럼 case에 raw값을 지정할 수 있다.
⚠️ 각 raw값은 열거형 선언에서 유일한 값으로 중복되어서는 안된다.
암시적으로 할당된 Raw 값 (Implicitly Assigned Raw Values)
enum Point: Int {
case a = 1 // 1
case b // 2
case c // 3
}
✔️ 위의 예제처럼 각 case별로 명시적으로 raw 값을 할당할 필요는 없다. 만약 raw값을 할당하지 않으면 스위프트에서 자동으로 값을 할당해 준다.
enum Point: Int {
case A = 1 // 1
case B // 2
case C // 3
}
var test:Point = .B
switch test.rawValue {
case 1:
print("1")
case 2:
print("2")
case 3:
print("3")
default:
print("no")
}
// 2
✔️ 위의 예제와 같이 raw값은 rawValue 프로퍼티를 사용해 접근할 수 있다.
enum Point: Int {
case a = 1 // 1
case b = 10 // 10
case c // 11
case d = 20 // 20
case e // 21
}
✔️ 위의 예제와 같이 Raw value가 없는 case는 바로 이전 case의 Raw Value에서 +1한 값으로 할당된다.
enum Point: Double {
case a = 1.0
case b = 2.0
case c
case d = 4.0
case e = 5.0
}
// ERR.
✔️ 위의 예제와 같이 Int형이 아닌 자료형으로 선언했을 때, 모든 case에 대해 Raw Value를 할당하지 않으면 에러가 발생한다.
enum Point: Double {
case a = 1.0
case b = 2
case c
case d = 4.0
case e = 5.0
}
✔️ 위의 예제와 같이 Int형이 아닌 다른 숫자(float, double)형을 사용할 경우 Raw Value를 생략하고 싶다면, 바로 이전 case의 Raw Value를 정수 값으로 해주면 된다.
enum Charenum:Character {
case c1 = "A"
case c2 = "B"
case c3 = "C"
}
✔️ 위의 예제와 같이 char형을 가지는 열거형도 Raw Value를 할당할 수 있다.
enum Charenum:Character {
case c1 = "A"
case c2
case c3 = "C"
}
// ERR.
✔️ 위의 예제와 같이 char형은 모든 case에 대한 Raw Value를 할당해주지 않으면 에러가 발생한다.
enum Nickname: String{
case yeo = "babo" // babo
case kim // kim
case lee // lee
}
✔️ 위의 예제와 같이 String은 Char형과 달리 Raw Value를 지정하지 않으면, case 이름과 동일한 Raw Value가 할당 됨.
Raw 값을 이용한 초기화 (Initializing from a Raw Value)
enum Nickname: String{
case yeo = "babo" // babo
case kim // kim
case lee // lee
}
var name1 = Nickname.init(rawValue: "babo") // yeo
var name2 = Nickname.init(rawValue: "ahn") // nil
✔️ 위의 예제와 같이 Raw Value를 이용해서 열거형 변수를 초기화 할 수 있다. 만약 열거형에 지정된 Raw Value이 없는 값으로 초기자를 지정하면 그 값은 nil이 된다.
연관 값 (Associated Values)
enum EnumName {
case caseName(Type)
case CaseName(Type, ... , Type)
}
✔️ 위의 예제와 같이 case 옆에 튜플 형태로 원하는 Type을 명시하면 된다.
enum Asia {
case korea(capital: String, randmark: String, population: Int)
case japan(capital: String, randmark: String)
}
let korInfo: Asia = .korea(capital: "Seoul", randmark: "Gyeongbokgung", population: 5000)
let japInfo: Asia = .japan(capital: "Tokyo", randmark: "Sensoji-temple")
✔️ 위의 예제와 같이 열거형에 직접 값을 지정해서 사용할 수 있다.
재귀 열거자 (Recursive Enumerations)
재귀 열거자는 다른 열거 인스턴스를 관계 값으로 갖는 열거형이다.
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
✔️ 위의 예제와 같이 재귀 열거자는 case 앞에 indirect 키워드를 붙여 표시한다.
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
✔️ 위의 예제와 같이 관계 값을 갖는 모든 열거형 case에 indirect 표시를 하고 싶으면 enum 키워드 앞에 indirect 표시를 하면 된다.
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
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"
'Swift > Swift 기본기' 카테고리의 다른 글
09. 프로퍼티 (Properties) (0) | 2023.03.18 |
---|---|
08. 클래스과 구조체 (Classes and Structures) (0) | 2023.03.18 |
06. 클로저 (Closures) (0) | 2023.03.18 |
05. 함수 (Functions) (0) | 2023.03.18 |
04. 제어문 (Control Flow) (0) | 2023.03.17 |