본문 바로가기
Swift/기본

타입 중첩

by 밤새는탐험가 2024. 4. 26.

타입 내부에 타입을 정의하고 구현할 수 있다. 

타입 내부에 새로운 타입을 선언하는 것을 중첩 타입이라고 한다. 

 

중첩된 타입의 동작 (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