네 enum 넌 무엇이냐..

sonny·2024년 9월 25일
2

TIL

목록 보기
5/48

오늘 팀원과 swiftUI를 찍먹하다가 enum 을 사용했는데 (막 따라치느라 검색을 못 해봄) 간단히 만들어볼 다마고치 유형의 프로젝트를 만드는 중, 성별을 지정하는 부분에서 사용 된 enum에 대해 간단히라도 짚고 넘어가려한다. 배운 것 같은데 기억이 나지 않는다.

Swift에서 enum은 관련된 값을 그룹으로 묶어 표현하는 데이터 타입인데, 특정한 집합의 값 중 하나를 선택할 수 있게 해주고 이를 통해 코드의 가독성이 높아질 뿐더러 오류도 줄일 수 있다고 하니.. 이번 TIL작성 겸 enum의 대해 이해하는 시간을 가져보자.

enum 기본 사용법

enum Transportation {
    case car
    case bus
    case bicycle
    case airplane
}

위 코드에서 Transportation이라는 이름의 enum을 정의하고 enum은 네 가지 교통 수단을 포함하고 있는데 enum의 각 값은 케이스(case)라고 하고, case 키워드를 사용하여 정의한다.

값 사용하기

enum 값을 사용할 때는 아래와 같이 간단하게 인스턴스를 생성할 수 있다.

let myTransportation = Transportation.car

이제 myTransportationTransportation enumcar 케이스를 참조한다. enum의 값을 사용하는 것은 코드의 의미를 명확하게 해주고 잘못된 값을 사용할 가능성을 줄여준다고 한다.

스위치문 함께 사용하기

enum은 스위치 문과 함께 사용할 때 그 진가를 발휘한다고 한다. 각 케이스에 대해 별도로 처리할 수 있어 코드의 흐름을 명확하게 만들 수 있다.

switch myTransportation {
case .car:
    print("차를 타고 이동합니다")
case .bus:
    print("버스를 타고 이동합니다")
case .bicycle:
    print("자전거를 타고 이동합니다")
case .airplane:
    print("비행기를 타고 이동합니다")
}

위 예시에서 switch 문을 사용하여 myTransportation의 값에 따라 각각 다른 메시지를 출력할 수 있다.

원시값(Raw Values)

먼저 원시값의 특징을 보자
자동 증가 : 원시값을 지정하지 않으면, 첫 번째 케이스는 0을 기본값으로 가지고 이후 케이스는 이전 케이스의 원시값에 1을 더한 값을 자동으로 가지게 된다. 그러나 정수형 원시값의 경우, 기본적으로 수동으로 값을 설정할 수도 있다.
타입 안전성 : 원시값은 열거형의 각 케이스에 대해 특정한 타입을 부여하고 잘못된 값이 사용되지 않도록 해준다.
단일 타입 : 열거형의 모든 케이스는 동일한 타입의 원시값을 가져야 한다.
(뭔 말인지 잘 모르겠다)

계속해서 보면 enum은 각 케이스에 기본값을 부여할 수 있는 원시값을 가질 수 있는데, 이 경우 모든 케이스는 같은 타입의 원시값을 가져야 한다.

enum TicketPrice: Int {
    case car = 20
    case bus = 10
    case bicycle = 5
    case airplane = 100
}

let myTicket = TicketPrice.car // 자동차를 선택
print(myTicket.rawValue) // 20

여기서 myTicketcar를 선택한 것이고, myTicket.rawValuecar의 원시값, 즉 20을 출력한다고 보면 된다.

조금 이해가 되어간다.

그러니까 각 이름에 붙이는 특별한 값이고, 코드가 더 이해하기 쉽게 만들어 주는데 숫자, 문자 등 다양한 값을 사용할 수도 있으며 이걸로 우리가 만들고자 하는 프로그램의 의미를 더 명확하게 전달할 수 있다.

연관값(Associated Values)

enum의 각 케이스에 추가 정보를 저장할 수 있는 연관값을 사용할 수 있는데, 이를 통해 더 복잡한 데이터 구조를 만들 수 있다고 한다. 연관값은 이해하기 좀 쉽게 동물로 해보았다.

enum Animal {
    case dog(name: String, age: Int)
    case cat(name: String, age: Int)
}


let myDog = Animal.dog(name: "sonny", age: 3) // 개의 이름은 "sonny", 나이는 3살이에요.
let myCat = Animal.cat(name: "gyeom", age: 2) // 고양이의 이름은 "gyeom", 나이는 2살이에요.


switch myDog {
case .dog(let name, let age):
    print("내 개의 이름은 \(name)이고, 나이는 \(age)살이에요.")
case .cat(let name, let age):
    print("내 고양이의 이름은 \(name)이고, 나이는 \(age)살이에요.")
}

여기서 dogcat 케이스는 각각 이름나이를 연관값으로 가지고 있으니 즉, 연관값은 개의 이름과 나이를, 고양이의 이름과 나이를 함께 저장할 수 있다.

여기서 myDog는 이름이 "sonny"의 나이가 3살인 개를 표현하고, myCat은 이름이 "gyeom"이고 나이가 2살인 고양이를 표현해준다.

위 코드를 실행하면 myDog에서 이름과 나이를 꺼내 출력이 되는 것이다. 이렇게 연관값을 사용하면 각 케이스에 대해 추가 정보를 간편하게 관리할 수 있다.

enum(열거형)의 좋은 점 간단 정리 ver.

가독성 향상 : 관련된 값을 그룹으로 묶어 코드의 의미를 명확하게 한다.

타입 안전성 : 잘못된 값이 사용될 가능성을 줄이고 컴파일 타임에 오류를 잡을 수 있다.

유연성 : 연관값을 사용하여 각 케이스에 다양한 정보를 추가할 수 있다.


음..

enum이 코드의 가독성과 안전성까지 높여주는 것에 이렇게까지 큰 역할을 하는지를 좀 알게 된 것 같다. 관련된 값을 그룹으로 묶어 표현할 수 있는 기능도 있고, 코드의 의미를 한번 더 확인해주면서 오류를 방지할 수 있는 좋은 친구였다.

무엇인가 특정한 값의 집합을 정의하고, 코드의 가독성을 높여주는 데이터 타입이라고 간단하게 정리하려고 했는데 여러가지 예시도 들어보고 자세하게 파고들어 공부해보니 점점 enum으로 정의해서 각 케이스를 사용하고 코드가 어떤 내용을 다루고 있는지도 이해할 수 있었다.

그리고 각 케이스에 특정한 원시값을 부여하면 잘못된 값이 사용될 가능성도 줄여준다고 하니 코드 작성 시 자신감 있게 필요한 상황에서 원시값을 한번 지정해보고 싶었다.

연관값을 이용해서 각 케이스에 추가 정보를 부여할 수 있다는 점이 좀 재밌었다. 예시도 쉽게 이해하고 싶어서 강아지고양이를 선택해 봤는데 잘한 듯하다. 덕분에 복잡한 데이터 구조를 다룰 수 있게? 그래도 조금은 이해할 수 있게 되어서 다양한 상황에서 유용하게 활용할 수 있을 것 같다.

마지막으로 스위치 문과 함께 사용할 때 enum과 스위치가 왜 한쌍인가 좀 알게됐다. enum은 관련된 값들을 그룹으로 묶는 역할을 하는데, 예를 든다면 요일이나 계절 같은 여러 값이 있는 것을 한번에 정리할 수 있다는 것이다.

다양한 데이터 구조를 유연하게 다룰 수 있는 enum !

앞으로 enum 을 활용해서 조금이나마 더 나은 코드를 작성할 수 있도록 노력해보겠다.

profile
iOS 좋아. swift 좋아.

6개의 댓글

comment-user-thumbnail
2024년 9월 25일

필수로 입력해야하는 타입들이 여러가지 있을 때 enum을 써야겠군요 스위치문 사용할 때 제가 빠트린 타입에 대해서 미리 알 수 있으니,, 넘넘 좋은 내용이네요 ^~^ 잘 읽고 갑니다

1개의 답글
comment-user-thumbnail
2024년 9월 25일

단일 타입 : 열거형의 모든 케이스는 동일한 타입의 원시값을 가져야 한다.
이 말은
enum TicketPrice: Int {
case car = 20
case bus = 10
case bicycle = 5
case airplane = 100
}
위 코드에서 열거형을 Int로 타입을 지정했고 모든 case들이 동일하게 Int type을 따르는 것처럼 원시값을 주기 위해선 타입을 통일해야 한다는 말입니다

1개의 답글