본문 바로가기
Swift

Nested Types(중첩 타입)에 관하여

by iOS 개린이 2023. 3. 13.

Nested Types(중첩 타입)

-공식문서에 따르면 

열거형은 종종 특정 클래스나 구조체의 기능을 지원하기 위해 만들어지는 경우가 있다.

이와 비슷하게 복잡한 타입의 컨텍스트 내에서 사용하기 위해 유틸리티 클래스나 구조체를 정의하는게 편리할 수 있다.

이를 위해 Swift에서 제공해주는 것이 Nested Type이다. 

(지원하는 타입의 정의 내에서 클래스, 구조체 및 열거형을 중첩할 수 있다.)

 

-야곰님의 Swift 문법책에 따르면

열거형은 특정 클래스나 구조체의 기능을 명확히 사용하기에 용이하다.

하지만 굳이 클래스나 구조체 외부에서 열거형을 사용할 필요가 없을 경우도 있다.

즉, 클래스나 구조체 내부에서 자신의 역할을 충실히 할 수 있도록 역할을 구분짓는 열거형을 선언해주고 자신의 내부에서만 사용할 수 있기를 원할 수 있다. 또는 특정 데이터 타입들을 하나의 클래스나 구조체에 구현하여 외부와의 혼선을 피하고 싶을 수도 있다.

이렇게 타입 내부에 새로운 타입을 선언해주는 것이 Nested Type이다.

 

먼말인지 모르겠지만 대충 특정 타입 내부에서 새로운 타입을  정의하는게 중첩 타입이라고 한다.

 

 

중첩 타입의 사용

 

class Person {
    
    enum Job{
        case jobless
        case programer
        case student
    }
    
    var job : Job = .jobless
}

class Student : Person {
    
    enum School{
        case elementary
        case middle
        case high
    }
    
    var school : School
    
    init(school : School) {
        
        self.school = school
        super.init()
        self.job = .student
    }
}

let personJob : Person.Job = .jobless
let studentJob : Student.Job = .student

let student : Student = Student.init(school: .middle)
print(student.job)    //student
print(student.school) //middle

 

Person 클래스 내부에 Job이라는 열거형을, Student 클래스 내부에 School이라는 열거형 타입을 정의했다.

여기서 중첩 타입은 Job과 School로 이에 접근하고 싶을 경우, 자신이 속해 있는 타입의 이름을 적고 .을 이용해서 접근해야 한다. ex) Person.Job 

이 순서를 통해서 중첩된 타입이 어떤 역할을 위해 만들어졌는지 알 수 있다.

 

또한 서브 클래스에서 슈퍼 클래스의 중첩 타입을 사용할 수도 있다.

Student 클래스는 Person을 상속받고 있으므로 Person의 중첩 타입인 Job을 Student 클래스를 통해 접근하는 것도 가능하다.

 

 

 

같은 이름의 중첩 데이터 타입 구현

 

struct Sports {
    
    enum GameType {
        
        case football
        case basketball
    }
    
    var gameType : GameType
    
    
    struct GameInfo {
        
        var time : Int
        var player : Int
    }
    
    var gameInfo : GameInfo {
        
        switch self.gameType {
            
        case .basketball:
            return GameInfo(time: 40, player: 5)
            
        case .football:
            return GameInfo(time: 90, player: 11)
        }
    }
}

struct Esports {
    
    enum GameType {
        
        case online
        case offline
    }
    
    var gameType : GameType
    
    
    struct GameInfo {
        
        var location : String
        var pakage : String
    }
    
    var gameInfo : GameInfo {
        
        switch self.gameType {
            
        case .online:
            return GameInfo(location: "www.online.co.kr", pakage: "LoL")
            
        case .offline:
            return GameInfo(location: "제주", pakage: "SA")
        }
    }
}



var basketball : Sports = Sports(gameType: .basketball)
print(basketball.gameInfo) //GameInfo(time: 40, player: 5)

var sudden : Esports = Esports(gameType: .offline)
print(sudden.gameInfo) //GameInfo(location: "제주", pakage: "SA")

let someGameType : Sports.GameType = .football
let anotherGameType : Esports.GameType = .online

 

Sports 구조체와 Esports 구조체를 만들었고, 내부에 각각 같은 이름의 중첩타입 열거형인 GameType, GameInfo를 선언해주었다.

GameType, GameInfo 는 이름과 타입이 모두 같지만, 서로 자신이 속해 있는 타입이 다르기 때문에 기능도 각각 다르게 수행되어야 한다.

만약 중첩타입이 없었다면, 외부에 새로운 열거형을 만들어 복잡하고, 긴 코드를 작성해주어야 했을 것이다.

하지만 중첩타입의 사용으로 각 구조체의 목적에 맞는 명확한 코드를 만들 수 있었다. 

이렇게 중첩타입은 타입의 목적성을 명확하게 해주기 때문에 직관적인 코드가 가능하고, 코드의 양도 줄여줄 수 있다.

 

이것이 바로 중첩타입의 힘

 

 

 

 

Reference :

-공식 문서로 공부하는 Swift (18) - 중첩 타입 (velog.io)

-야곰님의 스위프트 문법 개정 3판 

-Swift ) Nested Types (tistory.com)

'Swift' 카테고리의 다른 글

Where절에 관하여  (0) 2023.03.15
패턴에 관하여  (0) 2023.03.15
타입 캐스팅에 관하여  (0) 2023.03.13
모나드에 관하여  (0) 2023.03.10
고차함수에 관하여  (0) 2023.03.06