티스토리 뷰

Swift

[swift] Enum

진태우 2019. 3. 29. 12:57

열거형은 하나의 타입으로 정의해서 캡슐화함으로써 안전하고 간결한 코드를 작성하는 목적으로 사용됩니다.

swift에서의 열거형은 자료형과 원시값을 설정할 수 있고, 연산 프로퍼티 및 메소드도 정의할 수 있습니다.

또한 초기화 메소드를 정의할 수 있고, 프로토콜로 인한 기능 상속도 가능합니다.

다만 위에서도 말했듯이 연산 프로퍼티만 정의할 수 있고, 저장 프로퍼티는 정의할 수 없습니다.

저장 공간은 데이터를 연동한 각각의 case에만 있습니다. 이 부분은 아래에서 알아볼 것입니다.

참고로 enum도 value type이기 때문에 전달할 때 값이 복사됩니다.

 

아래는 열거형의 기본 형식입니다.

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

쉼표로 구분해서 구현도 가능합니다.

enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

enum을 구현하는 name은 CompassPoint, Planet과 같이 대문자로 시작해야하며, 복수형이 아닌 단수형으로 정의합니다.

 

아래는 enum 값을 할당하는 방식입니다.

두번째 라인에서는 변수의 타입을 CompassPoint라고 정의했기 때문에 .east라고만 해도 타입을 유추해서 사용이 가능합니다.

var directionToHead = CompassPoint.west
var directionToHead: CompassPoint = .east

 

enum을 사용해서 값을 비교할 때는 일반적으로 switch-case문을 사용합니다.

let somePlanet = Planet.earth
switch somePlanet {
    case .earth:
    print("Mostly harmless")
    default:
    print("Not a safe place for humans")
}
// Prints "Mostly harmless"

 

enum에는 enum의 모든 case를 리스트형으로 제공해주는 allCases 메소드를 가지고 있습니다.

enum Beverage: CaseIterable {
  case coffee, tea, juice
}

let numberOfChoices = Beverage.allCases.count
print("\(numberOfChoices) beverages available")
// Prints "3 beverages available"

for beverage in Beverage.allCases {
	print(beverage)
}
// coffee
// tea
// juice

 

Associated Data

enum의 각 case들이 연동된 데이터를 가질 수 있습니다.

아래는 연동된 데이터와 함께 enum을 선언하는 형식입니다.

enum FastFoodMenuItem {
  case hamburger(numberOfPatties: Int)
  case fries(size: FryOrderSize)
  case drink(String, ounces: Int)
  case cookie
}

enum FryOrderSize {
  case large
  case small
}

var menuItem = FastFootMenuItem.drink("Coke", ounces: 16)

// 연동타입 enum으로부터 정보 추출.
switch menuItem {
  case .hamburger(let pattyCount): print("a burger with \(pattyCount) patties!")
  case .fries: print("fries")
  case .drink(let brand, let ounces): print("a \(ounces)oz \(brand)")
  default: print("other")
}
// prints "a 16oz Coke"

 

enum에는 저장 프로퍼티를 가질 수 없다고 하였는데, self에 switch를 사용해서 데이터를 얻을 수 있습니다.

아래는 self에서 연동된 데이터를 가지고 스페셜 주문 여부를 체크하는 메소드를 구현한 예제입니다.

enum FastFoodMenuItem {
  // do Something...
  func isIncludedInSpecialOrder(number: Int)-> Bool {
	switch self {
  	  case hamburger(let pattyCount): return pattyCount == number
	  case fries, cookie: return true
	  case .drink(_, let ounces): return ounces == 16
	}
  }
}

 

Mutating

enum FastFoodMenuItem {
  // do Something...
  mutating func switchToBeingACookie() {
	self = .cookie
  }
}

 

enum에서 인스턴스 메소드를 이용해 self를 변경할 수 있습니다.

위 코드는 self를 변경하는 코드입니다.

이때 한 가지 알아야 할 것은 self를 변경하려 할 때는 mutating이라는 키워드를 함수 앞에 위치시켜야 합니다.

mutating 키워드를 붙여야 하는 이유는 enum은 값 타입이기 때문입니다.

값 타입은 힙 내부에 저장되지 않고 함수에 전달되거나 변수에 전달될 때 계속해서 복사됩니다.

매번 전체를 복사하게 되면 굉장히 비효율적이기 때문에 swift 내부에서 일부 내용이 변경되었을 때만 복제하도록 합니다.

이것을 쓰기시 복사 방식이라고 하는데 쓰기가 일어나는 함수에 mutating 키워드를 붙여 값이 변경되는 것을 알릴 수 있습니다.

즉, 쓰기가 실행되어 값을 변경시키는 함수라고 정의하는게 mutating 키워드의 의미입니다.

이것은 self 뿐만아니라 저장 프로퍼티 같이 내부 상태를 변경할 때도 사용됩니다.

또한 struct도 값 타입이기 때문에 struct의 인스턴트 메소드에서 내부 상태를 변경해야 할 경우에도 mutating 키워드를 사용합니다.

 

노션 페이지 임당~

https://www.notion.so/taewoojin/swift-Enum-7b7f478dabc8401190561441aec334cc

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함