오늘 팀원과 swiftUI
를 찍먹하다가 enum
을 사용했는데 (막 따라치느라 검색을 못 해봄) 간단히 만들어볼 다마고치 유형의 프로젝트를 만드는 중, 성별을 지정하는 부분에서 사용 된 enum
에 대해 간단히라도 짚고 넘어가려한다. 배운 것 같은데 기억이 나지 않는다.
Swift
에서 enum
은 관련된 값을 그룹으로 묶어 표현하는 데이터 타입인데, 특정한 집합의 값 중 하나를 선택할 수 있게 해주고 이를 통해 코드의 가독성이 높아질 뿐더러 오류도 줄일 수 있다고 하니.. 이번 TIL작성 겸 enum의 대해 이해하는 시간을 가져보자.
enum Transportation {
case car
case bus
case bicycle
case airplane
}
위 코드에서 Transportation
이라는 이름의 enum
을 정의하고 enum
은 네 가지 교통 수단을 포함하고 있는데 enum
의 각 값은 케이스(case)
라고 하고, case
키워드를 사용하여 정의한다.
enum
값을 사용할 때는 아래와 같이 간단하게 인스턴스를 생성할 수 있다.
let myTransportation = Transportation.car
이제 myTransportation
은 Transportation
enum
의 car
케이스를 참조한다. enum
의 값을 사용하는 것은 코드의 의미를 명확하게 해주고 잘못된 값을 사용할 가능성을 줄여준다고 한다.
enum
은 스위치 문과 함께 사용할 때 그 진가를 발휘한다고 한다. 각 케이스에 대해 별도로 처리할 수 있어 코드의 흐름을 명확하게 만들 수 있다.
switch myTransportation {
case .car:
print("차를 타고 이동합니다")
case .bus:
print("버스를 타고 이동합니다")
case .bicycle:
print("자전거를 타고 이동합니다")
case .airplane:
print("비행기를 타고 이동합니다")
}
위 예시에서 switch
문을 사용하여 myTransportation
의 값에 따라 각각 다른 메시지를 출력할 수 있다.
먼저 원시값의 특징을 보자
자동 증가
: 원시값을 지정하지 않으면, 첫 번째 케이스는 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
여기서 myTicket
은 car
를 선택한 것이고, myTicket.rawValue
는 car
의 원시값, 즉 20을 출력한다고 보면 된다.
조금 이해가 되어간다.
그러니까 각 이름에 붙이는 특별한 값이고, 코드가 더 이해하기 쉽게 만들어 주는데 숫자, 문자 등 다양한 값을 사용할 수도 있으며 이걸로 우리가 만들고자 하는 프로그램의 의미를 더 명확하게 전달할 수 있다.
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)살이에요.")
}
여기서 dog
와 cat
케이스는 각각 이름
과 나이
를 연관값으로 가지고 있으니 즉, 연관값은 개의 이름과 나이를, 고양이의 이름과 나이를 함께 저장할 수 있다.
여기서 myDog
는 이름이 "sonny"
의 나이가 3살인 개를 표현하고, myCat
은 이름이 "gyeom"
이고 나이가 2살인 고양이를 표현해준다.
위 코드를 실행하면 myDog
에서 이름과 나이를 꺼내 출력이 되는 것이다. 이렇게 연관값
을 사용하면 각 케이스에 대해 추가 정보를 간편하게 관리할 수 있다.
가독성 향상
: 관련된 값을 그룹으로 묶어 코드의 의미를 명확하게 한다.
타입 안전성
: 잘못된 값이 사용될 가능성을 줄이고 컴파일 타임에 오류를 잡을 수 있다.
유연성
: 연관값을 사용하여 각 케이스에 다양한 정보를 추가할 수 있다.
enum
이 코드의 가독성과 안전성까지 높여주는 것에 이렇게까지 큰 역할을 하는지를 좀 알게 된 것 같다. 관련된 값을 그룹으로 묶어 표현할 수 있는 기능도 있고, 코드의 의미를 한번 더 확인해주면서 오류를 방지할 수 있는 좋은 친구였다.
무엇인가 특정한 값의 집합을 정의하고, 코드의 가독성을 높여주는 데이터 타입이라고 간단하게 정리하려고 했는데 여러가지 예시도 들어보고 자세하게 파고들어 공부해보니 점점 enum
으로 정의해서 각 케이스를 사용하고 코드가 어떤 내용을 다루고 있는지도 이해할 수 있었다.
그리고 각 케이스에 특정한 원시값
을 부여하면 잘못된 값이 사용될 가능성도 줄여준다고 하니 코드 작성 시 자신감 있게 필요한 상황에서 원시값
을 한번 지정해보고 싶었다.
또 연관값
을 이용해서 각 케이스에 추가 정보를 부여할 수 있다는 점이 좀 재밌었다. 예시도 쉽게 이해하고 싶어서 강아지
와 고양이
를 선택해 봤는데 잘한 듯하다. 덕분에 복잡한 데이터 구조를 다룰 수 있게? 그래도 조금은 이해할 수 있게 되어서 다양한 상황에서 유용하게 활용할 수 있을 것 같다.
마지막으로 스위치
문과 함께 사용할 때 enum
과 스위치가 왜 한쌍인가 좀 알게됐다. enum
은 관련된 값들을 그룹으로 묶는 역할을 하는데, 예를 든다면 요일이나 계절 같은 여러 값이 있는 것을 한번에 정리할 수 있다는 것이다.
다양한 데이터 구조를 유연하게 다룰 수 있는 enum
!
앞으로 enum
을 활용해서 조금이나마 더 나은 코드를 작성할 수 있도록 노력해보겠다.
필수로 입력해야하는 타입들이 여러가지 있을 때 enum을 써야겠군요 스위치문 사용할 때 제가 빠트린 타입에 대해서 미리 알 수 있으니,, 넘넘 좋은 내용이네요 ^~^ 잘 읽고 갑니다