[Swift 공식문서 읽기]Type Casting

llim🧚🏻‍♀️·2021년 8월 24일
0

Swift

목록 보기
18/26
post-thumbnail

안녕하세요. 엘림입니다🙇🏻‍♀️

Swift 공식 문서를 정독하기 시리즈입니다!

제 스타일대로 정리했으니 추가적으로 더 필요한 정보는
공식문서 링크를 눌러 확인해주세용!

좀 더 편하게 보기위해 한국어로 번역된 사이트를 함께 확인했습니다!ㅎㅎ

자, 그럼 시작해볼까요

이 글은 공부하면서 작성한 글이기 때문에 잘못된 정보가 있을 수 있습니다.🥺
금방 잊어버릴... 미래의 저에게 다시 알려주기 위한 글이다보니
혹시라도 틀린 부분이 있다면, 댓글로 친절하게 알려주시길 부탁드립니다.🙏


타입캐스팅

타입캐스팅은 인스턴스의 타입을 확인하거나, 인스턴스를 같은 계층(hierachy)에 있는 다른 superclass나 subclass로 취급하는 방법입니다. 타입캐스팅에는 is와 as 두 연산자를 사용합니다. 타입캐스팅을 이용하면 특정 프로토콜을 따르는지도 확인할 수 있습니다.

class MediaItem {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Movie: MediaItem {
    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(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]

library가 갖고 있는 Movie,Song인스턴스의 공통 부모는 MediaItem이기 때문에 library는 타입 추론에 의해 [MediaItem] 배열의 형을 갖게 됩니다. library를 순회(iterate)하면 배열의 아이템은 Movie, Song 타입이 아니라 MediaItem타입이라는 것을 확인할 수 있습니다. 타입 지정을 위해서는 downcasting을 이용해야 합니다.

다운캐스팅

캐스팅은 실제 인스턴스나 값을 바꾸는 것이 아니라 지정한 타입으로 취급하는 것 뿐입니다.
특정 클래스 타입의 상수나 변수는 특정 서브클래스의 인스턴스를 참조하고 있을 수 있습니다. as?와 as! 연산자를 이용해 어떤 타입의 인스턴스인지 확인할 수 있습니다. as?는 특정 타입이 맞는지 확신할 수 없을때 사용하고, as!는 확실한 경우에 사용합니다.(단 as!로 다운캐스팅 했는데 지정한 타입이 아니라면, 런타임 에러가 발생합니다.)

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

형 확인

is 연산자를 이용해 특정 인스턴스의 타입을 확인할 수 있습니다.

var movieCount = 0
var songCount = 0

for item in library {
    if item is Movie {
        movieCount += 1
    } else if item is Song {
        songCount += 1
    }
}

print("Media library contains \(movieCount) movies and \(songCount) songs")
// "Media library contains 2 movies and 3 songs" 출력

Any, AnyObject의 타입 캐스팅

Any : 함수 타입을 포함해 모든 타입을 나타냅니다.(Int, String, 함수, 클로저 ... )
AnyObject : 모든 클래스 타임의 인스턴스를 나타냅니다.]

var things = [Any]()

things.append(0)
things.append(0.0)
things.append(42)
things.append(3.14159)
things.append("hello")
things.append((3.0, 5.0))
things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
things.append({ (name: String) -> String in "Hello, \(name)" })

for thing in things {
    switch thing {
    case 0 as Int:
        print("zero as an Int")
    case 0 as Double:
        print("zero as a Double")
    case let someInt as Int:
        print("an integer value of \(someInt)")
    case let someDouble as Double where someDouble > 0:
        print("a positive double value of \(someDouble)")
    case is Double:
        print("some other double value that I don't want to print")
    case let someString as String:
        print("a string value of \"\(someString)\"")
    case let (x, y) as (Double, Double):
        print("an (x, y) point at \(x), \(y)")
    case let movie as Movie:
        print("a movie called \(movie.name), dir. \(movie.director)")
    case let stringConverter as (String) -> String:
        print(stringConverter("Michael"))
    default:
        print("something else")
    }
}

Any 타입은 옵셔널 타입을 포함합니다.
하지만 Swift에서는 Any타입을 사용해야 하는 곳에 옵셔널을 사용하면 경고를 발생 시킵니다.

let optionalNumber: Int? = 3 things.append(optionalNumber) // 경고 things.append(optionalNumber as Any) // 경고 없음

오늘도 스위프트 공식문서를 정리해보았군욥~
다음편도 힘내보겠습니다!

감사합니다🙇🏻‍♀️

profile
한달 차 iOS 개발자입니다🐥

0개의 댓글