Swift문법 - (20)중첩타입

Youth·2022년 10월 9일
0

swift문법공부

목록 보기
20/27
post-thumbnail
post-custom-banner

중첩 타입

간단한 중첩타입

class Aclass {
		// 구조체인 Bstruct가 저장속성을 하나 가지고 있음
		// 그 저장속성은 enum타입인 Cenum타입임
    struct Bstruct { 
				// 열거형이 구조체인 Dstruct를 가지고 있음
        enum Cenum {
            case aCase
            case bCase

            struct Dstruct {       
            }
        }
        var name: Cenum
    }
}

각각의 요소에 접근하기 위해서는 아래와 같이 타입을 정해줘야한다

let aClass: Aclass = Aclass()

// 구조체는 멤버와이즈 이니셜라이즈가 자동구현되기때문에 init함수가 없지만
// 생성자를 이용해서 초기화가 가능하다
// bStruct에 접근하기 위해서는 속성도 Aclass를 타고들어가야한다
let bStruct: Aclass.Bstruct = Aclass.Bstruct(name: .bCase)

let cEnum: Aclass.Bstruct.Cenum = Aclass.Bstruct.Cenum.aCase

let dStruct: Aclass.Bstruct.Cenum.Dstruct 
						= Aclass.Bstruct.Cenum.Dstruct()

중첩타입은 왜 사용할까?

  • 특정 타입 내에서만 사용하기 위해서(Bstruct는 Aclass타입과 관계가 있고, Aclass없이는 의미가 없을 수 있음 그래서 범위를 명확히 한정)
  • 타입 간의 연관성을 명확히 구분하고, 내부 구조를 디테일하게 설계 가능

swift공식문서의 예제

struct BlackjackCard {
    // Suit(세트) 열거형
    enum Suit: Character {     
        case spades = "♠"
				case hearts = "♡"
				case diamonds = "♢"
				case clubs = "♣"
    }

    // 순서(숫자) 열거형
    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 Rank.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)
            }
        }
    }
   
    // 어떤 카드도, 순서(숫자)와 세트(Suit)를 가짐
    let rank: Rank
    let suit: Suit
    
    // (읽기) 계산속성
    var description: String {
        get {
            var output = "\(suit.rawValue) 세트,"
            output += " 숫자 \(rank.values.first)"
            
            if let second = rank.values.second {
                output += " 또는 \(second)"
            }
            
            return output
        }
    }
}

해석하는 방법

  1. blackjack인스턴스를 만들기 위해 rank(enum Rank)와 suit(enum Suit)를 인스턴스로 넣어줘야한다 → 인스턴스를 생성하면 특정 rank와 suit를 가지고 있게 된다
  2. 인스턴스의 .rank에 접근하면 내가 인스턴스를 생성할때 어떤 Rank의 case를 넣었는지에 접근이 가능하다.
  3. 이후에 .value 메서드를 호출하면 rank case에 따라 Value객체를 반환해준다

중첩타입을 공부해야하는 이유

  • API호출시 사용되는 경우많음
// 타입을 명시적으로 선언(: DateFormatter.Style <- 이부분)하지 않으면
// .full, .medium같이 간결하게 쓰지 못함
// DateFormatter.Style.full이런식으로 써야함

let setting1: DateFormatter.Style = .full
let setting2 = DateFormatter.Style.full

중첩타입은 특정 타입내에서 사용해서 타입간의 연관성을 구분하기 위해 사용한다

만약에 아래와 같이 선언을 했다면

“Style인건 알겠는데 무슨스타일인데?”라는 의문이 들 수 있다

enum Style {
    case full
    case long
    case medium
    case none
}

이런경우엔 아래와같이 선언을 해주면 어떤 style인지가 조금은더 명확해진다

struct DateFormatters {
    var style: Style
    
    // 중첩타입으로 선언
    enum Style {
        case full
        case long
        case medium
        case none
    }
}
  1. ⭐️중첩타입으로 선언된 API들을 볼줄 알아야함⭐️
    DateFormatter.Style.full
    (중간 타입에 대문자가 나오면, 중첩타입임을 인지)
  2. 실제 앱을 만들때 중첩 선언을 잘 활용해야함 (타입 간의 관계 명확성)
  3. 하나의 타입의 내부 구조(계층 관계 등)를 디테일하게 설계 가능
profile
AppleDeveloperAcademy@POSTECH 1기 수료, SOPT 32기 iOS파트 수료
post-custom-banner

0개의 댓글