Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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 31
Archives
Today
Total
관리 메뉴

iOS 개발 노트

🪴열거형(Enumeration) 본문

Swift

🪴열거형(Enumeration)

Daeyun Kwon 2024. 6. 12. 18:07

열거형이란

하나의 주제로 연관된 데이터 멤버들로 구성되어 있는 자료형 객체이다.

  • 문자열, 정수값 등 입력받아야 할 정보를 입력하는 대신, 선택하는 형식으로 동작됨.
  • 열거형에서 데이터들은 열거형 객체를 정의하는 시점에 함께 정의된다. -> 데이터를 함부로 삭제하거나 변경할 수 없으며, 변경하거나 삭제하려면 객체를 정의하는 구문을 직접 수정해야 함

열거형 사용 시 좋은 경우

  1. 원치 않는 값이 잘못 입력되는 것을 막고 싶을 때
  2. 입력받을 값을 미리 특정할 수 있을 때
  3. 제한된 값 중에서만 선택할 수 있도록 강제하고 싶을 때

열거형으로 정의할 수 있는 데이터 집합의 예:

  • 성별: 남, 여, X-gender
  • 기기: iPhone, iPad, watch, mac, airPods
  • 색상: 빨강, 노랑, 초록
  • 국가: 한국, 일본, 중국, 미국, 호주, 캐나다

열거형의 정의

열거형 객체를 정의할 때는 enum 키워드를 사용한다. 데이터 멤버들은 case 키워드와 함께 정의함.

  • 열거형의 이름은 파스칼 표기법을 따른다.
enum 열거형이름 {
    case 멤버값1
    case 멤버값2
    case ...
}


enum Direction {
    case north
    case south
    case east, west
}

let N = Direction.north

print(N) //north

또는 static let 키워드를 통해 타입 프로퍼티로 정의하는 것도 가능함!

enum Direction {
    static let north = "북쪽"
    static let west = "서쪽"
    static let south = "남쪽"
    static let east = "동쪽"
}

또는 연산 프로퍼티를 정의하는 것도 가능함!

enum Direction {
    var north: String {
        get {
            return "북쪽"
        }
    }

    var west: String {
        get {
            return "서쪽"
        }
    }

    var south: String {
        get {
            return "남쪽"
        }
    }

    var east: String {
        get {
            return "동쪽"
        }
    }
}

switch문 + 열거형

switch문을 사용하면 열거형의 멤버와 비교하는 분기 구문을 사용할 수 있다.

  • 열거형에 정의된 멤버를 switch 구문의 case 블록 비교에 전부 사용하면 default 구문은 생략 가능하다.

💡 반대로, 모든 멤버를 다 비교할 필요가 없다면 꼭 비교해야 할 일부 멤버만 비교하고 나머지는 default 구문에 맡기면 된다.

switch 비교대상 {
    case 열거형.멤버1:
        //실행할구문
    case 열거형.멤버2:
        //실행할구문
    ...
}


enum Direction {
    case north
    case south
    case east, west
}

var directionToHead = Direction.north


switch directionToHead {
case .north:
    print("북쪽")
case .south:
    print("남쪽")
case .east:
    print("동쪽")
case .west:
    print("서쪽")
}

원시값(RawValue)

case에 있는 멤버 자체로는 의미 전달이 부족할 경우가 있다.
Swift에서는 열거형의 멤버에 실질적인 값을 할당할 수 있도록 허용하고 있다. 멤버에 대입된 값은 필요할 때 꺼낼 수 있다.

  • rawValue으로 사용 가능한 타입: String, Character, Int, Double, Float

멤버에 대입할 값의 자료형을 열거형 이름 뒤에 타입 어노테이션으로 표기해야 한다.

enum HTTPCode: Int {
    case OK = 200
    case NOT_MODIFY = 304
    case INCORRECT_PAGE = 404
    case SERVER_ERROR = 500
}

멤버에 할당된 값을 읽을 때는 rawValue 속성을 사용해야 한다.

  • 각 멤버들은 유니크한 값을 가져야 한다.(중복값 X)
enum HTTPCode: Int {
    case OK = 200
    case NOT_MODIFY = 304
    case INCORRECT_PAGE = 404
    case SERVER_ERROR = 500
}

print(HTTPCode.OK) //OK
print(HTTPCode.OK.rawValue) //200

열거형 객체의 멤버와 값은, 사용하는 시점에서 멤버에 보조 값을 설정할 수 있는 방법도 있다. 이렇게 설정된 값을 Associated Values이라고 한다.

Associcated Value는 실행 시점에서 값을 저장해야 할 필요가 있을 때 요긴하게 사용하면 될 것 같다.

enum ImageFormat {
    case JPEG
    case PNG(Bool)
    case GIF(Int, Bool)
}

var newImage = ImageFormat.PNG(true)

print(newImage) //PNG(true)

newImage = ImageFormat.GIF(256, false)

print(newImage) //GIF(256, false)

CaseIterable

열거형에 CaseIterable 프로토콜을 채택하면,
allCases이라는 프로퍼티를 사용 가능해지는데 이를 사용하면 배열처럼 사용이 가능하다.

enum Number: Int, CaseIterable {
    case one = 1
    case two = 2
    case three = 3
}

print(Number.allCases[0].rawValue) // 1
print(Number.allCases[1].rawValue) // 2
print(Number.allCases[2].rawValue) // 3

Unfrozen Enumeration

멤버가 추가될 가능성이 있는 열거형을 의미한다.

  • switch 문에서 모든 case에 대한 처리가 명시되지 않았을 때, 컴파일러가 경고를 발생시키는 대신 처리되지 않은 case에 대해 특정 동작을 수행하도록 지정할 수 있게 해줍니다.

열거형을 switch 문으로 처리할 때, 모든 case에 대한 처리가 명시되지 않았을 경우 @unknown default를 사용하여 처리되지 않은 case에 대한 기본적인 동작을 정의할 수 있습니다.

enum Direction {
    case north
    case south
    case east
    case west
}

let test = Direction.east

switch test {
case .north:
    print("북쪽을 선택했네요")
@unknown default:
    print("알 수 없는 방향입니다.")
}

frozen Enumeration

더 이상 case가 추가되거나 변경되지 않는 즉, 불변성을 가진 열거형을 의미한다.

  • @frozen이 선언되어 있다면 frozen Enumeration을 의미한다.
  • 컴파일러의 동작이나 내부 최적화 과정에서 사용된다.
  • case가 변경되지 않는 것이 확실하기 때문에 default로 선언되는 과정을 없앨 수 있고 컴파일 속도를 향상시킬 수 있다.
  • 프레임워크나 라이브러리에서 API 안정성을 위해 사용된다.
    @frozen enum HTTPMethod: String, CaseIterable {
      case get = "GET"
      case post = "POST"
      case put = "PUT"
      case delete = "DELETE"
    }

'Swift' 카테고리의 다른 글

🪴Async/Await에 대해서  (0) 2024.06.23
🪴Swift는 Type-Safe한 언어!  (0) 2023.09.22
🪴변수명 표기법  (0) 2023.06.29