타입 내부에 타입을 정의하고 구현할 수 있다.
타입 내부에 새로운 타입을 선언하는 것을 중첩 타입이라고 한다.
중첩된 타입의 동작 (Nested Types in Action)
BlackjackCard 라는 구조체 정의한다.
해당 구조체에는 Suit 와 Rank 라는 2개의 중첩된 열거형을 포함한다.
✔ 블랙잭에서 에이스 카드의 값은 1 또는 11이다. 해당 내용은 Rank 열거형 내에 중첩된 Values 라는 구조체로 나타낸다.
Suit 열거형은 기호를 나타내는 원시 Character 값과 함께 4개의 일반적인 카드 모양을 나타낸다.
enum Suit: Character {
case spades = "♠", hearts = "♡", diamonds = "♢", clubs = "♣"
}
Rank 열거형은 카드값을 나타내는 원시 Int 값과 함께 13개의 카드 순위를 나타낸다.
Rank 열거형은 Values 라는 자신의 중첩된 구조체를 더 정의한다.
Values 구조체는 2개의 프로퍼티를 정의한다.
✔ Int 타입의 first 와 Int? (옵셔널 Int) 타입의 second
Rank 열거형은 Values 구조체의 인스턴스를 반환하는 values 라는 계산된 프로퍼티도 정의한다.
숫자 카드에 대해서는 순위의 원시 Int 값을 사용한다.
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 구조체 자체는 rank 와 suit 의 2개의 프로퍼티를 가지고 있다.
rank 와 suit 에 저장된 값을 사용하는 description 이라는 계산된 프로퍼티도 정의한다.
description 프로퍼티는 화면에 표시하기 위해 두 번째 값이 있는지 확인하고, 두 번째 값에 대해 상세 설명을 추가한다.
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
}
BlackjackCard 전체 코드
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
}
}
BlackjackCard 는 사용자 지정 초기화 구문이 없는 구조체이기 때문에 암시적 멤버별 초기화 구문을 갖고 있다.
theAceOfSpades 라는 새로운 상수를 초기화 하기 위해 초기화 구문을 사용할 수 있다
let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
// Prints "theAceOfSpades: suit is ♠, value is 1 or 11"
중첩된 타입 참조 (Referring to Nested Types)
외부에서 중첩된 타입을 사용하기 위해 해당 이름에 중첩된 타입의 이름을 접두사로 붙인다.
let heartsSymbol = BlackjackCard.Suit.hearts.rawValue
// heartsSymbol is "♡"
'Swift > 기본' 카테고리의 다른 글
타입 추론, 타입 어노테이션 (0) | 2024.04.27 |
---|---|
ARC 3편 (클로저에서의 강한 참조 순환) (0) | 2024.04.26 |
DispatchQueue.main과 DispatchQueue.global (1) | 2024.04.20 |
ARC 2편 - 강한 참조 순환 (0) | 2024.04.19 |
ARC 1편 - ARC 란? (0) | 2024.04.19 |