GGURUPiOS
Swift 공식 문서 정리 - (19) Type Casting 본문
Type Casting(타입 캐스팅)
타입 캐스팅은 인스턴스의 타입을 확인하거나 인스턴스를 같은 계층에 있는 다른 슈퍼클래스나 서브클래스로 취급하는 방법임
타입캐스팅에는 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")
]
library가 갖고있는 Movie, Song 인스턴스의 공통 부모는 MediaItem 이기때문에
library는 타입추론에 의해 [MediaItem] 배열의 형을 갖게 됨
library를 순회하면 배열의 아이템은 Movie, Song 타입이 아니라 MediaItem 타입임
타입지정을 위해서는 downcasting 을 이용해야 함
타입 확인
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" 출력
다운 캐스팅
특정 클래스 타입의 상수나 변수는 특정 서브클래스의 인스턴스를 참조하고 있을 수 있음
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
캐스팅은 실제 인스턴스나 값을 바꾸는 것이 아닌, 지정한 타입으로 취급하는 것임
Any, AnyObject의 타입 캐스팅
스위프트에서는 두가지 특별한 타입이 제공됨
- Any: 함수 타입을 포함해 모든 타입
- 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")
}
}
위의 예제에서 Int, Double 뿐 아니라 튜플, 함수도 Any 타입에 포함될 수 있다는 것 확인
'Swift > 공식문서 정리 ( 문법 )' 카테고리의 다른 글
Swift 공식 문서 정리 - (21) Extensions (0) | 2023.05.14 |
---|---|
Swift 공식 문서 정리 - (20) Nested Types (0) | 2023.05.14 |
Swift 공식 문서 정리 - (18) Concurrency (0) | 2023.05.14 |
Swift 공식 문서 정리 - (17) Error Handling (0) | 2023.04.28 |
Swift 공식 문서 정리 - (16) Optional Chaining (0) | 2023.04.28 |