iOS & Swift

[Swift] 타입 캐스팅이란 ? (is, as)

석지한 2022. 5. 11. 15:50
반응형

 오늘은 타입 캐스팅이 무엇인가에 대해서 포스팅해보려고 한다. 항상 무의식적으로 타입 캐스팅을 쓰고 있는데, 뭔가 주입식으로 써야 한다!라고 어디선가 본 이유로 쓰는 것이지, 왜 쓰는 것인지 본질적으로 알고 있는 것은 아니라 판단하여 공식문서 및 다양한 블로그를 참고하여 글을 작성하려고 한다.

 

 타입 캐스팅의 종류에는 is, as가 있다.

 인스턴스의 타입을 확인하거나, 해당 인스턴스를 superclass / subclass로 취급하는 방법이다.

 

Checking Type

공식문서

- is 연산자를 이용하면 특정 인스턴스의 타입을 확인할 수 있다.

 

 내용이 빈약하기 때문에, 더 찾아보았다.

 

- 표현식이 Type과 동일하거나, 표현식이 Type의 서브 클래스인 경우 --> True 반환

- 이외에는 false를 반환

- 리턴값은 항상 Bool형

 

--> 내가 원하는 타입인지를 판단하거나, 서브클래스인 경우를 판단하기 위하여 사용한다.

 

표현식 is 타입

의 형태로 사용할 수 있다.

 

 

Type Casting

업 캐스팅

- 서브 클래스의 인스턴스를 슈퍼 클래스의 타입으로 참조

- 업 캐스팅은 항상 성공

- as 연산자를 사용. as 연산자는 컴파일 단계에서 캐스팅이 실행되고, 항상 특정 Type으로 캐스팅이 성공할 때만 사용이 가능하여 업 캐스팅에 사용됨.

 

다운 캐스팅

- 특정 클래스 타입의 상수를 참조

- 슈퍼 클래스의 인스턴스를 하위 클래스의 타입으로 참조

- 다운 캐스팅은 실패할 수 있음

- 따라서 as? or as!를 사용

- as?는 런타임 시점에 다운 캐스팅을 하며, 실패할 경우 nil을 리턴

- as!는 런타임 시점에 다운 캐스팅을 하나, 실패할 경우 에러가 발생한다

 

--> 가능한 as?를 사용하자.

 

다운 캐스팅 예시 

class MediaItem { // 상위 클래스인 MediaItem 선언
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Movie: MediaItem { // MediaItem을 상속받는 Movie, Song 선언
    var director: String
    init(name: String, director: String) {
        self.director = director
        super.init(name: name)
    }
}

class Song: MediaItem {
    var artist: String
    init(name: String, artist: String) {
        self.artist = artist
        super.init(name: name)
    }
}
let library = [ // Movie, Song 두개의 클래스를 갖고 있는 배열 선언
    Movie(name: "Casablanca", director: "Michael Curtiz"),
    Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
    Movie(name: "Citizen Kane", director: "Orson Welles"),
    Song(name: "The One And Only", artist: "Chesney Hawkes"),
    Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]
// the type of "library" is inferred to be [MediaItem]
for item in library {
    if let movie = item as? Movie {
        print("Movie: \(movie.name), dir. \(movie.director)")
    } else if let song = item as? Song {
        print("Song: \(song.name), by \(song.artist)")
    }
}

// Movie: Casablanca, dir. Michael Curtiz
// Song: Blue Suede Shoes, by Elvis Presley
// Movie: Citizen Kane, dir. Orson Welles
// Song: The One And Only, by Chesney Hawkes
// Song: Never Gonna Give You Up, by Rick Astley

// as? 연산자를 사용하여 다운캐스팅 한 후, if let을 통해 안전하게 옵셔널 값을 추출함.

 

 

참고

https://jusung.gitbook.io/the-swift-language-guide/language-guide/18-type-casting

https://babbab2.tistory.com/127?category=828998 

https://onelife2live.tistory.com/9

반응형