티스토리 뷰

swift/문법

15. Swift 문법 - Enumeration

DevBee 2020. 10. 21. 11:19

1. Enumeration Types

열거형은 연관된 상수들을 하나로 묶은 자료형으로 독립적인 자료형입니다. 열거형의 각 상수들은 Enumeration Case 라고 하고 이런 상수들의 묶음을 Enumeration Type 이라고 합니다. 열거형은 코드의 가독성과 안정성을 높이기 위해 많이 사용됩니다.

 

문법은 다음과 같습니다.

enum TypeName {
    case caseName
    case caseName, caseName
}

 

간단한 열거형을 만들어 사용 방법을 알아보겠습니다.

enum Alignment {
    case left
    case center
    case right
}

Alignment.center

// 열거형 case 역시 코드에서 의미가 변하지 않는 하나의 값으로
// 일반적인 리터럴 1 등과 유사
var textAlignment = Alignment.center

// 열거형 케이스인 것을 알기 때문에 열거형 이름을 생략 가능
textAlignment = .left

// 열거형 케이스에 등록된 값만 저장할 수 있음
// textAlignment = .Left - 에러

// 열거형 비교
if textAlignment == .center {
    
}

switch textAlignment {
case .left:
    print("left")
case .center:
    print("center")
case .right:
    print("right")
}

// 출력 결과
left

 

2. Raw Value

독립적인 열거형 안에 또 다른 값을 저장할 수 있는데 이 값을 Raw Value 라고 합니다. 필수 값은 아니며 Enumeration case 와 연관된 또 다른 값을 함께 저장해야 할 때 사용합니다.

 

RawValueType 은 String, Character, Number Type 으로 제한되며 선언 시 지정된 원시 값은 추후 변경할 수 없습니다.

 

문법은 다음과 같습니다.

enum TypeName: RawValueType {
    case caseName = Value
}

 

이전에 사용했던 열거형 타입에 Raw Value 를 추가하여 사용하는 방법에 대해 알아보겠습니다.

// 값을 지정하지 않으면 0부터 하나씩 증가
enum Alignment: Int {
    case left
    case center
    case right = 100
}

Alignment.left.rawValue    // 0
Alignment.center.rawValue  // 1
Alignment.right.rawValue   // 100

// 값 변경 불가
// Alignment.right.rawValue = 10 - 에러

// 열거형 생성자
// 동일한 rawValue 를 가지는 값을 리턴
// 일치하는 값이 없는 경우는 nil 을 리턴
Alignment(rawValue: 0)    // left
Alignment(rawValue: 200)  // nil

// 값을 지정하지 않으면 caseName 과 동일한 값
enum Weekday: String {
    case sunday
    case monday = "MON"
    case tuesday
    case wednesday
    case thursday
    case friday
    case saturday
}

Weekday.sunday.rawValue  // sunday
Weekday.monday.rawValue  // MON

// 반드시 원시 값을 직접 저장해야 함
// Character 형은 Int 형처럼 자동으로 증가하는 값이 아니며
// caseName 또한 한 문자가 아니기 때문
enum ControlChar: Character {
    case tab = "\t"
    case newLine = "\n"
}

 

3. Associated Values

연관값이란, Enumeration case 에 연관된 값을 함께 저장하는 것을 의미합니다. Associated Values 는 하나의 케이스에 서로 다른 연관 값을 지정할 수 있습니다. 따라서, 선언 시점이 아니라 새로운 열거형 값을 생성할 때 저장합니다. Raw Value 와 유사하지만 함께 사용할 수는 없습니다. 

 

문법과 사용법을 알아보며 Raw Value 와의 차이점을 확인해보겠습니다.

enum TypeName {
    case caseName(Type)
    case caseName(Type, Type, ...)
}
enum VideoInterface {
    case div(width: Int, height: Int)
    case hdmi(Int, Int, Double, Bool)
    case displayPort(CGSize)
}

var input = VideoInterface.div(width: 2048, height: 1536)

switch input {
case .div(2048, 1536):
    print("div 2048 x 1536")
case .div(2048, _):
    print("div 2048 x Any")
case .div:
    print("div")
case .hdmi(let width, let height, let version, var audioEnable):
    print("hdmi \(width) x \(height)")
case let .displayPort(size):
    print("dp")
}

// 출력 결과
div 2048 x 1536

// input 은 VideoInterface 타입이기 때문에
// 해당 열거형 타입의 케이스 중에서는 다른 케이스로 변경이 가능
input = .hdmi(3840, 2160, 2.1, true)

 

4. Enumeration Case Pattern

연관 값을 가진 열거형 케이스를 매칭 시킬 때 사용하는 패턴을 알아보겠습니다. 해당 패턴은 switch, if, guard, for-in, while 문에서 사용이 가능합니다.

 

먼저 문법은 다음과 같습니다.

// 연관 값을 개별적으로 바인딩 할 때 사용
case Enum.case(let name):
case Enum.case(var name):

// 전체 연관 값의 바인딩 방식이 동일한 경우에 사용
case let Enum.case(name):
case var Enum.case(name):

 

이 패턴을 사용하는 시점에는 열거형 타입을 대부분 추론할 수 있으므로, 열거형 타입을 생략한 상태로 사용이 가능합니다.

 

간단하게 사용 예를 살펴보겠습니다.

enum Transportation {
    case bus(number: Int)
    case taxi(company: String, number: String)
    case subway(lineNumber: Int, express: Bool)
}

var tpt = Transportation.bus(number: 7)

switch tpt {
case .bus(let n):
    print(n)
case .taxi(let c, var n):
    print(c, n)
case let .subway(l, e):
    print(l, e)
}

// 출력 결과
7

tpt = Transportation.subway(lineNumber: 2, express: false)

if case let .subway(2, express) = tpt {
    if express {
        
    } else {
        
    }
}

if case .subway(_, true) = tpt {
    print("express")
}
let list = [
    Transportation.subway(lineNumber: 2, express: false),
    Transportation.bus(number: 4412),
    Transportation.subway(lineNumber: 7, express: true),
    Transportation.taxi(company: "SeoulTaxi", number: "1234")
]

for case let .subway(n, _) in list {
    print("subway \(n)")
}

// 출력 결과
subway 2
subway 7

for case let .subway(n, true) in list {
    print("subway \(n)")
}

// 출력 결과
subway 7

for case let .subway(n, true) in list where n == 2 {
    print("subway \(n)")
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함