본문 바로가기

iOS/Swift

Swift 열거형(enumeration)

열거형  개요

 

미리 정의된 값 집합으로 구성된 사용자 지정 데이터 유형을 만드는 데 사용된다.

(연관된 항목들을 묶어서 표현할 수 있는 타입)

열거형은 일반적으로 switch 문을 사용할 때와 같이 코드 내에서 결정을 내릴 때 사용된다.

 

일반적인 열거형의 코드의 형태는 이렇다

 enum 열거형이름 {
    case ..
    case ..
    ...
 }

 

아래 예제를 보며 계속 설명하겠다.

enum Temperature {
    case hot
    case warm
    case cold
}

 

위의 Temperature 라는 enum에서는 어떤 case에도 값이 할당되지 않았다.

이러한 타입의 열거형은 기본적으로 미리 정의된 상태들 중 하나를 참조하는 데 사용된다.

아래 코드와 같이 사용될 수 있다.

func displayTempInfo(temp: Temperature) {
    switch temp {
    case Temperature.hot:
        print("It is hot.")
    case Temperature.warm:
        print("It is warm.")
    case Temperature.cold:
        print("It is cold.")
    }
}

displayTempInfo(temp: Temperature.hot)
displayTempInfo(temp: Temperature.warm)
displayTempInfo(temp: Temperature.cold)

 

아래에 함수를 호출하면서 전달인자로 열거형의 case를 보내주면

switch case 구문을 통해 열거형의 케이스를 확인하여

아래 출력문을 볼 수가 있다

It is hot.
It is warm.
It is cold.

 

열거형 내의 개별 케이스에는 연결된 값이 있을 수도 있다.

예를 들어 'cold' 열거형 케이스가 온도값과 연결되어야 앱이 추위와

동결 조건을 구별할 수 있다고 하면 아래의 코드같이 정의할 수 있다.

enum Temperature {
    case hot
    case warm
    case cold(centigrade: Int)
}


이를 통해 switch문으로 아래 코드같이 온도도 확인할 수 있다

func displayTempInfo(temp: Temperature) {
    switch temp {
    case Temperature.hot:
        print("It is hot.")
    case Temperature.warm:
        print("It is warm.")
    case Temperature.cold(let centigrade) where centigrade <= 0:
        print("Ice warning: \(centigrade) degrees.")
    case Temperature.cold:
        print("It is cold.")
    }
}

 

cold 열거형 값이 함께 함수에 전달되려면 온도도 함께 전달이 되어야한다.

displayTempInfo(temp: Temperature.cold(centigrade: -10))

결과는 이렇다

Ice warning: -10 degrees.

 

또 다른 열거형을 사용하는 방법 중 하나는

열거형에 타입을 채택하고 해당 타입의 값을 각 case에 넣어주는 것이다.

아래 코드로 확인해보자.

 

아래 코드와 같이 String 타입을 채택하고 각 case에 String 값을 넣어주었다

enum Season: String {
	case Spring = "spring"
	case Summer = "summer"
	case Autumn = "autumn"
	case Winter = "winter"
}

 

이 값을 사용하려면

열거형.케이스.rawValue 로 값에 접근할 수 있다.

Print(Season.Spring.rawValue)
Print(Season.Summer.rawValue)
Print(Season.Autumn.rawValue)
Print(Season.Winter.rawValue)

이렇게 print를 해보면 아래와 같이 출력되는 것을 확인할 수 있다.

spring
summer
autumn
winter

 

다른 예제를 풀어보며 더 자세히 알아가봅시다.

 

열거형을 사용하여 주사위의 면을 나타내는 타입을 정의하고,

랜덤한 주사위의 면을 반환하는 함수를 작성하면된다.

 

단계별로 하나씩 나아가보자

 

먼저 Dice 라는 이름을 가진 열거형을 케이스별로 나열해 봅시다.

enum Dice {
	case one, two, three, four, five, six
}

 

여기서 먼저 CaseIterable 이라는 프로토콜부터 함께 알아보고 가자

https://developer.apple.com/documentation/swift/caseiterable

 

CaseIterable | Apple Developer Documentation

A type that provides a collection of all of its values.

developer.apple.com

영어를 잘하지못하여 대충 설명을 해보자면 CaseIterable을 채택한 열거형은 모든 컬렉션에서 사용할 수 있다고 써있다.

즉 컬렉션이라고 한다면 Set, Array, Dictionary 가 있을 텐데 이 모든 컬렉션에서 사용할 수 있다라는

열거형 타입의 모든 케이스들을 배열처럼 사용할 수 있다는 것이다.

아래 코드를 보며 좀 더 확인해보자.

 

아래 코드와 같이 열거형 이름: 여기에 CaseIterable 프로토콜을 채택하면 되는 것이다.

이렇게 하면 어떤 코드를 작성할 수 있냐면

enum Dice: CaseIterable { 
	case one, two, three, four, five, six
}

 

코드를 보자면 Dice라는 열거형 타입을 반환하는 함수가 있다.

함수안에 정의된 코드를 보면 Dice.allCases 라는 메서드가 있는데

이 메서드는 모든 케이스들이 들어가있는 배열형태로 만들어주는 메서드이다

이 배열에서 randomElement 라는 메서드를 통해 Dice의 모든 케이스중 랜덤으로

하나를 반환받을 수 있다.

func rollDice() -> Dice {
	Dice.allCases.randomElement()!
}

 

그래서 이 함수를 6번 호출하면서 주사위를 6번 굴리는 것처럼

보일 수 있도록 구현할 수 있는 것이다.

(1...6).forEach { _ in
	print("주사위의 면은 \(rollDice())입니다.")   // 주사위의 면은 two입니다.
}

 

switch case 구문을 이용한 예제를 하나 보여주면서 마무리하겠다.

대충 요약을 해보자면

열거형을 사용하여 방향을 나타내는 타입을 정의하고,
현재 위치와 방향을 매개변수로 받아서 다음 위치를 반환하는 함수를 작성하여
호출하는 것이다.
(위치는 x, y 좌표로 표현하고, 방향은 상, 하, 좌, 우로 표현한다.)
enum Direction {
	case up, down, left, right
}

func move(position: (Int, Int), direction: Direction) -> (Int, Int) {
	let x: Int = position.0
	let y: Int = position.1
	switch direction {
	case.up:
		return (x, y + 1)
	case.down:
		return (x, y - 1)
	case.left:
		return (x - 1, y)
	case.right:
		return (x + 1, y)
	}
}

let currentPosition = (x: 0, y: 0)

var nextPosition: (x: Int, y: Int) = move(position: currentPosition, direction: .right)
print("다음 위치는 (\(nextPosition.x), \(nextPosition.y))입니다.")  // 다음 위치는 (1, 0)입니다.

nextPosition = move(position: currentPosition, direction: .left)
print("다음 위치는 (\(nextPosition.x), \(nextPosition.y))입니다.")  // 다음 위치는 (-1, 0)입니다.

nextPosition = move(position: currentPosition, direction: .up)
print("다음 위치는 (\(nextPosition.x), \(nextPosition.y))입니다.")  // 다음 위치는 (0, 1)입니다.

nextPosition = move(position: currentPosition, direction: .down)
print("다음 위치는 (\(nextPosition.x), \(nextPosition.y))입니다.")  // 다음 위치는 (0, -1)입니다.

'iOS > Swift' 카테고리의 다른 글

Swift 동기(SYNC) 비동기(ASYNC)  (1) 2023.10.19
Swift 에러 핸들링  (1) 2023.10.18
Swift stride(from:to:by:)  (1) 2023.09.23
Swift replacingOccurrences(of:with:)  (0) 2023.09.17
프로퍼티  (0) 2023.08.05