나의 발자취

열거형 본문

앱 개발/iOS

열거형

달모드 2022. 5. 27. 01:03

열거형(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)기가 용량입니다.")

}

Comments