나의 발자취
열거형 본문
열거형(enumerations)은 타입이다
커스텀 타입(enum, class, struct)
basic type VS custom type
: 연관된 상수(케이스)들을 하나의 이름으로 묶은 자료형
열거형 쓰는 법
- enum 뒤의 타입이름은 대문자로 쓰고, case는 뒤의 케이스 이름은 소문자로 쓴다.(swift 4.0~)
- (1) 한 줄씩 쓰는 방법 (2) 콤마로 한줄에 적는 방법이 있다.
enum Weekday {
case monday
case tuesday
case wednesday
case thursday
case friday
case saturday
case sunday
}
enum CompassPoint {
case north, south, east, west
}
언제 사용하는지?
한정된 사례(정해진 갯수) 안에서 정의할 수 있을때.
- 월 / 화 / 수 / 목 / 금 / 토 / 일
- 동 / 서 / 남 / 북
- 좌로 정렬 / 가운데 정렬 / 우측 정렬
- 초등학교 / 중학교 / 고등학교 / 대학교
- 남 / 여
- 가위 / 바위 / 보
열거형을 사용하면 코드의 가독성과 안정성이 높아져 명확한 분기 처리가 가능하다.
열거형 사용법
var today: Weekday = Weekday.monday
today = .tuesday
// today 에 들어있는 타입(Weekday)이 명확하기 때문에 생략하고 .tuesday 로 표기가 가능하다.
분기 처리 - switch 문
switch today {
case .monday:
print("오늘은 월요일입니다.")
case .tuesday:
print("오늘은 화요일입니다.")
case .wednesday:
print("오늘은 수요일입니다.")
case .thursday:
print("오늘은 목요일입니다.")
case .friday:
print("오늘은 금요일입니다.")
case .saturday:
print("오늘은 토요일입니다.")
case .sunday:
print("오늘은 일요일입니다.")
}
열거형의 원시값(raw value)
열거형의 원시값은 매칭되는 기본값(정수/문자열)을 정해, 열거형을 좀 더 쉽게 활용 가능
// 여러가지 형태로 원시값을 정의 가능 (Hashable한 - Int / String / Character / Double 등 가능)
enum Alignment: Int {
case left
case center = 1 // 로 설정
case right
}
// 원시값 입력안하면 0, 1, 2 이렇게 자동으로 저장됨 (정수의 경우 숫자가 하나씩 증가)
// 1(설정시), 2, 3
// 0, 2(설정시), 3
var align = Alignment(rawValue: 0) // left
var num = Alignment.center.rawValue // 1
=========================================================
문자도 매칭이 가능하다.
enum Alignment1: String {
case left = "L"
case center = "C"
case right = "R"
}
let align = Alignment(rawValue: 0) // left. 인스턴스 생성시 - 옵셔널타입으로 리턴 (실패가능)
let leftValue = Alignment.center.rawValue // "1". 접근연산자를 통해 원시값 자체에도 접근가능
Alignment1(rawValue: "C") // center. (가능하지만) 문자 방식으로는 잘 사용하지는 않음. Int/String
let centerValue = Alignment1.center.rawValue // "C"
원시값의 활용
// 가위 바위 보 열거형 만들기
enum RpsGame: Int {
case rock
case paper
case scissors
}
// 실제 앱을 만들때는
RpsGame(rawValue: 0)! // 생성자 타입으로 부를 경우 옵셔널 타입이 됨.
RpsGame(rawValue: 1)
RpsGame(rawValue: 2)
// 논리적으로 nil이 될 수 없다면
let number = Int.random(in: 0...100) % 3 // 3을 조금 더 멋지게 처리할 수 있는 것은 고급내용에서 다룸
print(RpsGame(rawValue: number)!) // 출력은 하지만 문자열은 아님에 주의
// 옵셔널값을 안전하게 벗겨서 사용
if let r = RpsGame(rawValue: 0) {
print(r) // 출력은 하지만 문자열은 아님에 주의
}
// 행성 열거형 만들기
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
let planet = Planet(rawValue: 1)!
// Planet.mercury
let num = planet.rawValue
print(num)
열거형의 연관값(associated value)
열거형의 연관값은 구체적인 추가정보를 저장하기 위해 사용한다.
enum Computer {
case cpu(core: Int, ghz: Double)
case ram(Int, String)
case hardDisk(gb: Int)
}
Computer.cpu(core: 2, ghz: 4)
열거형의 연관값 쓰는 경우
각 케이스별로 상이한 특징이 있고, 그것을 저장 / 활용할 필요가 있을 때
- 개별케이스마다 저장할 형식을 따로 정의(자료형에 제한이 없음 / 튜플의 형태)
- 하나의 케이스에 서로다른 연관값을 저장할 수 있음 ===> 선언시점이 아니라, 새로운 열거형 값을 생성할때 저장
let myChip1 = Computer.cpu(core: 8, ghz: 3.5)
let myChip2 = Computer.cpu(core: 4, ghz: 2.0)
let myChip3 = Computer.ram(16, "DRAM")
let myChip4 = Computer.ram(4, "SRAM")
let myChip5 = Computer.ram(32, "DRAM")
let myChip6 = Computer.hardDisk(gb: 128)
let myChip7 = Computer.hardDisk(gb: 512)
// 원시값을 활용한다면 -> 변경 불가능
enum Computer1: String {
case cpu = "6coreX2.6ghz"
case ram = "32GBXDDR4"
case hardDisk = "256gb"
}
// 모든 케이스들을 다 만들수가 없음
원시값과 연관값의 차이
- 1) 자료형 선언 방식: 선언하는 위치가 다름
- 2) 선언 형식: (1) 원시값- 2가지(정수,문자열)중 1가지 선택 / (2)연관값- 튜플의 형태로 형식 제한 없음
- 3) 값의 저장 시점: (원시값: 선언시점 / 연관값: 새로운 열거형 값을 생성할때 )
- 4) 서로 배타적: 하나의 열거형에서 원시값과 연관값을 함께 사용하는 것은 불가능
<원시값>
enum Weekday {
case monday
case tuesday
case wednesday
case thursday
case friday
case saturday
case sunday
}
<연관값>
enum Computer {
case cpu(core: Int, ghz: Double)
case ram(Int, String)
case hardDisk(gb: Int)
}
연관값의 활용
var chip = Computer.cpu(core: 8, ghz: 2.0)
switch chip {
case .cpu(core: 8, ghz: 3.1):
print("CPU 8코어 3.1GHz입니다.")
case .cpu(core: 8, ghz: 2.6):
print("CPU 8코어 2.6GHz입니다.")
case .ram(32, _):
print("32기가램 입니다.")
default:
print("그 이외의 칩에는 관심이 없습니다.")
}
// 연관값을 가진 케이스를 패턴 매칭시키기
switch chip {
case let .cpu(a, b): // let a = 연관값, let b = 연관값
print("CPU \(a)코어 \(b)GHz입니다.")
case let .ram(a, _):
print("램 \(a)기가램 입니다.")
case let .hardDisk(a) :
print("하드디스크 \(a)기가 용량입니다.")
}
'앱 개발 > iOS' 카테고리의 다른 글
열거형과 switch문 (0) | 2022.06.03 |
---|---|
옵셔널 타입의 내부 구조 (0) | 2022.05.27 |
컬렉션 관련 이론: KeyValuePairs, Copy-On-Write 최적화 (0) | 2022.05.26 |
스위프트 컬렉션(3) Set (0) | 2022.05.26 |
스위프트 컬렉션(2) 딕셔너리 (0) | 2022.05.25 |