// 열거형
// 열거형에 포함된 상수들은 상수라고 부르지 않고 Enumeration case 혹은 case로 부름
// 코드의 가독성, 안정성 향상
// 열거형을 사용하지 않았을때 발생하는 오류
//let left = 0
//let center = 1
//let right = 2
//
//var aligment = center
// 규칙을 모르더라도 값만으로 어떤 의미인지 파악할 수 있게
// 가독성은 증가했지만 문자열이기 때문에 오타가 발생할 수도 있고 비교 기준을 명확히해야함(대소문자 등)
let left = "left"
let center = "center"
let right = "right"
var aligment = center
// 대문자라서 false
if aligment == "Center" {
}
// 열거형 case는 독립적인 값
enum Alignment {
case left
case right
case center
}
Alignment.center
var textAlignment = Alignment.center
print(textAlignment)
// 앞에서 열거형을 작성했기 때문에 어떤 열거형인지 추론할 수 있기 때문에 .left만 적어줘도 된다.
textAlignment = .left
// enum case는 값이기 때문에 == 으로 구분한다.
if textAlignment == .center {
}
//switch
switch textAlignment {
case .left:
print("left")
case .right:
print("right")
case .center:
print("center")
}
Raw Values
// 원시값
// case와 함께 다른 값을 선언해야 할때 사용
enum Alignment: Int {
// Int가 raw Value이고 값을 지정해주지 left부터 순서대로 0 1 2
case left
case right
case center
case leftInt = 5
case rightInt // 요곤 그전 값 +1
}
Alignment.leftInt.rawValue
Alignment.left.rawValue
Alignment.rightInt.rawValue
// rawValue에 새로운 값 넣는거 불가능
// Alignment.right.rawValue = 5
// rawValue에 해당하는 case 리턴됨
Alignment(rawValue: 5)
// rawValue에 해당하는 값 없으면 nil
Alignment(rawValue: 200)
enum Weekday: String {
case sunday
case monday = "MON"
case tuesday
case wednesday
case thursday
case friday
case saturday
}
// rawValue가 String이면 case에 해당하는 String리턴
Weekday.sunday.rawValue
// 값이 있으면 지정한 값 리턴
Weekday.monday.rawValue
// rawValue를 Character로 선언한 경우에는 반드시 rawValue를 직접 지정해야 한다.
enum ControlChar: Character {
case tab = "\t"
case newLine = "\n"
}
Associated Value
// enum case에 연관된 값을 저장한다.
enum VideoInterface: String {
case dvi = "1028x768"
case hdmi = "2048x1536"
case displayPort = "3840x2160"
}
// 이렇게하면 문자를 숫자로 추출해야한다.
// 이렇게 원시값으로 해상도를 저장하면 전부 공유
// associated Values
// 1. 저장할 자료형을 개별 case별로 가능
// 2. () 튜플로 선언
// 3. case뒤에 선언
// 4. 선언할 수 있는 형식에 제한이 없음
// 5. 하나의 케이스에서 서로 다른 자료형을 선언할 수 있음
enum AssociatedVideoInterface {
// named Tuple로 선언가능
case dvi(width: Int, height: Int)
// Unnamed Tuple로도 선언가능
case hdmi(Int, Int, Double, Bool)
case displayPort(CGSize)
}
var input = AssociatedVideoInterface.dvi(width: 2048, height: 1536)
// 연관값을 코드로 확인할 때는 주로 switch문을 사용
// enumeration case parttern
switch input {
case .dvi(width: 2048, height: 1536):
print("dvi 2048 x 1536")
case .dvi(2048, _): // 와일드 카드 패턴으로 높이를 생략
print("div 2048 x Any")
case .dvi: // 연관값 무시하고 case만 일치시킬 때
print("dvi")
case .hdmi(let width, let height, let version, let audioEnabled): // 연관값을 상수로 바인딩
print("hdmi \(width)x\(height)")
case let .displayPort(size): // 모든 연관 값을 동일한 case로 바인딩 하는 경우
print("dp")
}
input = .hdmi(3080, 2160, 2.1, true)
input
Enumberation Pattern
// Enumeration Case Pattern
// 연관값을 가진 열거형 case를 매칭시킬때 사용
// switch, if, guard, for-in문에서 사용
enum TransPortation {
case bus(number: Int)
case taxi(company: String, number: Int)
case subway(lineNumber: Int, express: Bool)
}
var tpt = TransPortation.bus(number: 7)
// swich문에서 enumeration case pattern
switch tpt {
case .bus(let n): // bus case를 매칭시키고 연관값은 n 상수에 바인딩
print(n)
case .taxi(let c, var n):
print(c, n)
case let .subway(l, e):
print(l, e)
}
tpt = TransPortation.subway(lineNumber: 2, express: false)
// if문에서 enumeration case pattern
if case let .subway(2, express) = tpt { // .subway의 lineNumber가 2 일때 true
if express {
} else {
}
}
// 지금은 값을 바인딩하지 않아서 case 뒤에 let 이나 var 키워드를 쓰지 않음
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)")
}
for case let .subway(n, true) in list {
print("subway \(n)")
}
for case let .subway(n, true) in list where n == 2 {
print("subway \(n)")
}