About Swift – “enum과 원시 값, 연관 값”
About Swift – “enum과 원시 값, 연관 값”
Swift의 열거형
열거형은 관련있는 데이터들이 멤버로 구성되어 있는 자료형을 의미합니다. 스위프트 공식문서의 열거형에 대한 설명은 다음과 같습니다.
An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.
열거형은 관련 값 그룹에 대한 공통 유형을 정의하고 코드 내에서 유형이 안전한 방식으로 해당 값으로 작업할 수 있도록 합니다.
열거형 정의하기
enum SomeEnumeration {
// enumeration definition goes here
}
스위프트에서 열거형은 위와 같이 정의합니다.
enum CompassPoint1 {
case north
case south
case east
case west
}
enum CompassPoint2 {
case north, south, east, west
}
위의 경우처럼 case를 여러 개 사용할 수도 있고, 아래의 경우처럼 하나의 case에 여러 개의 멤버를 나열하는 것도 가능합니다.(위의 코드 블록에서)
enum CompassPoint1 {
case north
case south
case east
case west
}
print(CompassPoint1.north) //north
var x = CompassPoint1.west
var y : CompassPoint1
var z : Int
print(type(of: x)) //CompassPoint1
print(type(of: z)) //Int
x = .east
y = .south
print(x) //east
print(y) //south
var x = CompassPoint1.west
의 줄에서는 열거형의 이름과 그 멤버까지 정해 주었고, var y : CompassPoint1
에는 그 형만 정해주었습니다. 아래의 print
는 x
의 타입을 출력해주는데, 우리가 만든 그 열거형명이 출력되는 것을 볼 수 있습니다. 예컨대 var z : Int = 5
라고 한 후 print(type(of:z))
라는 코드를 작성 후 실행한다면 Int
형이라고 알려주겠지요.
위 코드에서 15, 16줄을 보면 .east, .south처럼 열거형명 자체를 생략해 버렸는데, 이는 위의 10, 11줄에서 x와 y가 CompassPoint1 형임을 확정지어주었기 때문입니다. 등호 좌변의 변수 타입이 확정되었을 때에는, 15줄과 16줄의 코드와 같이 열거형명을 생략할 수 있습니다.
열거형의 멤버들에 기능 부여하기
enum arm_workouts {
case biceps
case triceps
}
var member1 : arm_workouts
member1 = .biceps
switch member1 {
case .biceps:
print("barbell curl")
case .triceps:
print("push down")
}
var member2 : arm_workouts
member2 = .triceps
switch member2 {
case .biceps:
print("arm curl machine")
case .triceps:
print("bench press")
}
print(member1)
print(member2)
// barbell curl
// bench press
// biceps
// triceps
열거형의 인스턴스를 만들고 각 멤버들마다 switch – case 를 사용해서 기능을 부여할 수 있습니다.
열거형의 멤버들에 메소드 넣기
enum workouts : String {
case biceps
case triceps
case chest
case back
func printWorkout(){
switch self {
case .biceps, .back:
print("당기기 운동")
case .triceps, .chest:
print("밀기 운동")
}
}
func printWorkout2(){
switch self{
case .biceps, .triceps:
print("팔 근육")
case .chest, .back:
print("상체 대근육")
}
}
}
workouts.back.printWorkout()
workouts.back.printWorkout2()
//당기기 운동
//상체 대근육
열거형을 정의하던 도중 갑자기 function 키워드가 등장하였는데, 열거형의 멤버로서 메소드 자체가 들어갈 수도 있습니다.
열거형의 rawValue
아래 코드를 살펴보겠습니다.
enum workouts : Double {
case biceps
case triceps
case chest = 10
case back
}
print(workouts.biceps.rawValue)
print(workouts.triceps.rawValue)
print(workouts.chest.rawValue)
print(workouts.back.rawValue)
//0.0
//1.0
//10.0
//11.0
print(workouts.biceps.rawValue)
로 wokrouts의 rawValue를 출력해 보면 각각 어떠한 숫자들이 출력되는 것을 확인할 수 있습니다.
이것은 바로 rawValue라는 것인데, enum workouts : Double {
로 시작되는 열거형의 정의 부분을 보면 Double
이라는 키워드를 볼 수 있습니다. 그것은 rawValue의 타입을 의미합니다.
case chest = 10
의 코드에서처럼 rawValue 값을 지정해 주면, 원래는 0부터 1씩 증가해 나가지만 정해준 그 값 이후부터 1이 더해져 10 다음 11이 rawValue가 되게 됩니다. rawValue의 값을 Double으로 정해 주었기 때문에 1.0 처럼 형변환 되어 출력됩니다. Int형도 가능합니다.
String형 값을 갖는 열거형의 rawValue는 어떨까요?
enum fish : String{
case guppy = "구피"
case discus = "디스커스"
case angelfish
}
print(fish.guppy.rawValue)
print(fish.discus.rawValue)
print(fish.angelfish.rawValue)
fish라는 열거형의 원시 값들은 String 형이 됩니다. guppy는 “구피” 처럼 말이지요. 하지만 case angelfish에는 rawValue 값을 지정해 주지 않았습니다. 이러한 경우에는, 자동으로 원시 값에 case 이름이 할당됩니다. 실제로, 세 번째 프린트문의 결과는 angelfish가 됩니다.
Associated value
enum SBD : String{
case deadLift = "컨벤셔널, 120kg"
case benchPress = "클로즈 그립, 50kg"
case squat = "하이바, 150kg"
}
var mySBD = SBD.deadLift
print(mySBD.rawValue)
위의 코드를 살펴보면 SBD라는 열거형은 String이라는 원시 값을 가집니다. 데드리프트라고 불리우는 운동에는 스모 데드리프트, 컨벤셔널 데드리프트 등 여러 가지 종류가 있는데, 위의 코드에서 “컨벤셔널, 120kg” 라는 것이 문자열 하나로 되어 있어 종류나 무게 값만 추출하거나 변경하는 등 다루기에 단점이 있습니다.
enum SBD{
case deadLift(String, Int)
case benchPress(String, Int)
case squat(String, Int)
}
var mySBD = SBD.deadLift("컨벤셔널 데드리프트", 120)
mySBD = SBD.deadLift("스모 데드리프트", 190)
switch mySBD {
case .deadLift(let type, let weight):
print(type)
print(weight)
case .benchPress(let type, let weight):
print(type)
print(weight)
case .squat(let type, let weight):
print(type)
print(weight)
}
//스모 데드리프트
//190
이렇게 연관 값을 활용해 준 경우에는 “중량” 부분이나 “종목 이름” 부분을 더 쉽게 다루거나 변경할 수 있습니다.
참고 자료 : https://youtu.be/kkfOV2LvzAA (한성현 교수님의 유튜브 강의입니다.)