열거형은 특정 클래스 또는 구조체의 기능을 지원하기 위해 생성된다. 유사하게 더 복잡한 타입의 컨텍스트 내에서 사용하기 위해 순수하게 유틸리티 클래스와 구조체를 정의하는 것이 편리할 수 있다. 이를 위해 Swift는 중첩된 타입(nested types)을 정의할 수 있으며 지원하는 타입의 내에서 열거형, 클래스, 그리고 구조체를 정의할 수 있다.
다른 타입 내에서 타입을 중첩하려면 지원하는 타입의 외부 중괄호 내에 정의를 작성해야 한다. 타입은 필요한만큼의 수준으로 중첩될 수 있다.
Nested Types in Action
블랙젝 게임에서 사용되는 게임 카드를 모델링하는 BlackjackCard라는 구조체를 정의한다. Suit와 Rank라는 2개의 중첩된 열거형을 포함한다.
블랙잭에서 에이스 카드의 값은 1 또는 11입니다. 이러한 특징은 Rank 열거형 내에 중첩된 Values라는 구조체로 나타낸다.
struct BlackjackCard {
// nested Suit enumeration
enum Suit: Character {
case spades = "♠", hearts = "♡", diamonds = "♢", clubs = "♣"
}
// nested Rank enumeration
enum Rank: Int {
case two = 2, three, four, five, six, seven, eight, nine, ten
case jack, queen, king, ace
struct Values {
let first: Int, second: Int?
}
var values: Values {
switch self {
case .ace:
return Values(first: 1, second: 11)
case .jack, .queen, .king:
return Values(first: 10, second: nil)
default:
return Values(first: self.rawValue, second: nil)
}
}
}
// BlackjackCard properties and methods
let rank: Rank, suit: Suit
var description: String {
var output = "suit is \(suit.rawValue),"
output += " value is \(rank.values.first)"
if let second = rank.values.second {
output += " or \(second)"
}
return output
}
}
Suit 열거형은 기호를 나타내는 원시 Character 값과 함께 4개의 일반적인 카드 모양을 나타낸다.
Rank 열거형은 카드 값을 나타내는 원시 Int 값과 함께 가능한 13개의 카드 순위를 나타낸다. (원시 Int 값은 Jack, Queen, King, 그리고 Ace 카드에는 사용되지 않는다).
Rank 열거형에 Values라는 중첩된 구조체를 정의한다. 이 구조체는 대부분의 카드는 하나의 값을 가지지만 에이스 카드는 2개의 값을 가지는 사실을 캡슐화한다. Values 구조체는 다음과 같이 2개의 프로퍼티를 정의한다.
- Int 타입의 first
- Int? 또는 옵셔널 Int 타입의 second
Rank는 Values 구조체의 인스턴스를 반환하는 values라는 연산 프로퍼티도 정의한다. 카드의 순위를 고려하고 그 순위를 기반으로 적절한 값으로 새로운 Values 인스턴스를 초기화한다. jack, queen, king, 그리고 ace에 대한 특별한 값을 사용한다. 숫자 카드에 대해서는 순위의 원시 Int 값을 사용한다.
이름과 카드의 값의 설명을 만들기 위해 rank와 suit에 저장된 값을 사용하는 description 이라는 연산 프로퍼티도 정의한다. description 프로퍼티는 화면에 표시하기 위해 두 번째 값이 있는지 확인하고 있으면 두 번째 값에 대한 상세 설명을 추가한다.
blackjackCard는 사용자 지정 생성자가 없기 때문에 암시적 멤버별 생성자를 가지고 있다. theAceOfSpades라는 새로운 상수를 초기화하기 위해 생성자를 사용할 수 있다.
let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
// Prints "theAceOfSpades: suit is ♠, value is 1 or 11"
Rank와 Suit은 BlackjackCard 내에 중첩되어 있지만 타입은 컨텍스트로부터 유추될 수 있기 때문에 이 인스턴스의 초기화는 케이스 이름(. ace와. spades)만으로 열거형 케이스를 참조할 수 있다. 위 예제에서 description 프로퍼티는 스페이드의 에이스는 1 또는 11의 값을 가지고 있다고 올바르게 출력한다.
Referring to Nested Types
let heartsSymbol = BlackjackCard.Suit.hearts.rawValue
// heartsSymbol is "♡"
'Swift 공식 문서' 카테고리의 다른 글
Protocols (0) | 2024.01.18 |
---|---|
Extensions (0) | 2024.01.16 |
Type Casting (0) | 2024.01.15 |
Concurrency (0) | 2024.01.11 |
Error Handling (0) | 2024.01.08 |