μλ νμΈμ, μ§μΉμ§ μκ³ λμμ¨ κ³΅μλ¬Έμ μ 리 ν¬μ€ν μ λλ€. μμ¦ μ ν λ벨λ‘νΌ μμΉ΄λ°λ―Έλ λΆμλ€, μ€ν°λλ νλ€, νλ©΄μ κ°μΈκ³΅λΆλ₯Ό μ‘°κΈ μνν νκ³ μλλ°, μ λ§ λ°μ±νλ μλ―Έλ‘λ€κ° μ€λμ μ’ κ³΅λΆλ μμΉ¨ μΌμ° μμν΄λ΄€μ΄μ... κ°μ μ΄μ보μμγ μ...
κ°μμ°λ€κ³ λ νλλ°, μΈμ λ λ§μ‘±μ€λ¬μ΄ κ°μμ μ΄μλ³Έμ μ μμ§ μλ κ²κ°μμ. μΈμ μ―€, μ κΈ°λμΉμ λ§μ‘±ν λ§ν 곡λΆμ μμ μ±μ°κ³ ν루λ₯Ό μ λ§ μμ°¨κ² μ΄ μ μμκΉμ? ν ν ν ... λ Έλ ₯ν΄λ΄ μλ€ λͺ¨λ νμ΄ν κ·ΈλΌ κ³΅μλ¬Έμ μ 리 μμ!
Swift document chap.19 Type Casting λ°λ‘κ°κΈ°
Type Casting
- νμ μΊμ€ν μ μΈμ€ν΄μ€μ νμ μ νμΈνκ±°λ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό ν΄λΉ ν΄λμ€ κ³μΈ΅ ꡬ쑰μ μνΌ ν΄λμ€λ μλΈν΄λμ€λ‘ μ·¨κΈνλ λ°©λ²μ΄λ€.
- Swiftμ νμ μΊμ€ν μ is, as μ°μ°μλ‘ κ΅¬νλλ€.
- νμ μ νμΈνκ±°λ λ€λ₯Έ νμ μΌλ‘ μΊμ€νΈ νλ κ²μ κ°λ¨ν ννμΌλ‘ μ 곡νλ€.
- νμ μΊμ€ν μ μ¬μ©νμ¬ νλ‘ν μ½μ μ€μνλμ§ νμΈ ν μλ μλ€.
νμ μΊμ€ν μ μν ν΄λμ€ κ³μΈ΅ ꡬ쑰 μ μΈ
ν΄λμ€μ μλΈ ν΄λμ€μ κ³μΈ΅κ΅¬μ‘°μ ν¨κ» νμ μΊμ€ν μ μ¬μ©νμ¬ νΉμ ν΄λμ€μ μΈμ€ν΄μ€ νμ μ νμΈνκ³ ν΄λΉ μΈμ€ν΄μ€λ₯Ό λμΌν κ³μΈ΅ λ΄μ λ€λ₯Έ ν΄λμ€λ‘ μΊμ€ν ν μ μλ€.
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
MediaItem μ΄λΌλ κΈ°λ³Έ ν΄λμ€λ₯Ό μ μνλ€. μ΄ ν΄λμ€λ λμ§νΈ λ―Έλμ΄ λΌμ΄λΈλ¬λ¦¬μλ μ΄λ€ μ’ λ₯μ νλͺ©μλ κΈ°μ΄ κΈ°λ₯μ μ 곡νλ€. name μμ±κ³Ό init 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)
}
}
MediaItem μ μλΈν΄λμ± νμ¬ λ κ°μ λ€λ₯Έ μλΈν΄λμ€λ₯Ό λ§λ€μλ€.
첫λ²μ§Έ νμ ν΄λμ€μΈ Moiveλ μν λ° νλ¦μ λν μΆκ° μ 보λ₯Ό κ°κ³ μλ€. μ΄λ MediaItem μ΄λΌλ κΈ°μ΄ ν΄λμ€ μμ director μμ±κ³Ό ν΄λΉ μμ±μλ₯Ό μΆκ°λ‘ κ°κ³ μλ€.
λλ²μ§Έ νμ ν΄λμ€μΈ Song μ κΈ°λ³Έ ν΄λμ€ MediaItem μμ artist μμ±κ³Ό μμ±μλ₯Ό μΆκ°νλ€.
let library = [
Movie(name: "Casablanca", director: "Michael Curtiz"),
Song(name: "Blue Suede Shoes", director: "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" μ νμ
μ [MediaItem] μ΄λΌκ³ μΆλ‘ ν¨
μ μΈκ°μ classλ₯Ό νμ©νμ¬ library λΌλ μμ λ°°μ΄μ μμ±νλ€. library λ°°μ΄μ νμ μ μ΄λ₯Ό μ΄κΈ°ννλ λ°°μ΄ κΈμ κ°μ λ΄μ©μΌλ‘ μΆλ‘ νλ€. μ€μννΈλ Moiveμ Songμ κ³΅ν΅ μμ ν΄λμ€κ° MediaItem μμ μ΄λμ΄λΌ μ μμΌλ―λ‘, library λ°°μ΄μ Array<MediaItem> νμ μ΄λΌκ³ μΆλ‘ νκ² λλ€. (νμ μΊμ€ν )
νμ§λ§, libraryμ μ μ₯ν νλͺ©μ μ΄λ©΄μ μ¬μ ν Movie, Song μΈμ€ν΄μ€μΈλ°, μ΄ λ°°μ΄μΌ μννκ² λλ©΄ λ°νλλ νμ μ MediaItem νμ μ΄μ§ Moive λ Songμ΄ μλλ€. λ³Έλ μμ μ νμ μΌλ‘ μμ νκΈ° μν΄μλ, νμ μ κ²μ¬νκ±°λ (check), λ€λ₯Ένμ μΌλ‘ downcastνμ¬ μ΄μ©ν΄μΌ νλ€.
νμ κ²μ¬ (Check)
is μ°μ°μλ₯Ό μ΄μ©ν΄ νΉμ μΈμ€ν΄μ€μ νμ μ νμΈ ν μ μλ€. νμ κ²μ¬ μ°μ°μλ μΈμ€ν΄μ€κ° κ·Έ νμ ν΄λμ€μ΄λ©΄ trueλ₯Ό λ°ννκ³ , μλλ©΄ falseλ₯Ό λ°ννλ€.
μλ μ½λλ library λ°°μ΄μ μννκ³ μμ΄ν μ΄ νΉμ νμ μΌ λ λ§λ€ κ·Έ μ«μλ₯Ό μ¦κ°νλ μ½λμ΄λ€.
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" λ₯Ό μΈμν¨
μ μ½λμμ for-in ꡬ문μμ library λΌλ λ°°μ΄μ λͺ¨λ νλͺ©μ μ κ·Όνλ€. νμ§λ§ libraryλ Array<MediaItem> νμ μ΄κΈ° λλ¬Έμ MediaItem νμ μ΄ λ°νλκ² λλλ°, μ΄λ is μ°μ°μλ₯Ό μ¬μ©νμ¬ ν΄λΉ νλͺ©μ΄ MediaItemμ μλΈν΄λμ€μΈ Movie, Song ν΄λμ€μΈμ§ νμΈν μ μλ€.
λ€μ΄μΊμ€ν (Downcasting)
νΉμ ν΄λμ€ νμ μ μμμ λ³μλ μλΈν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μ°Έμ‘°ν μ μλ€. λ§μ½ μ΄λ¬ν κ²½μ°κ° λ§μ‘±νλ€κ³ μκ°νλ κ²½μ° as?, as! λ₯Ό μ¬μ©νμ¬ μλΈν΄λμ€ νμ μΌλ‘ λ€μ΄μΊμ€νΈ ν μ μλ€.
- as?
- λ€μ΄μΊμ€νΈ νλ €λ νμ μ μ΅μ λ κ°μ λ°ν
- μΊμ€ν μ μ€ν¨νλ©΄ nil κ°μ λ°ν (λ€μ΄μΊμ€νΈμ μ±κ³΅ μ¬λΆκ° λΆνμ€ν λ μ¬μ©νλ©΄ μ’μ)
- 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
μ μμ λ libraryμ κ° MediaItemμ λ°λ³΅νμ¬ κ° νλͺ©μ μ μ ν μ€λͺ μ μΈμνλλ‘ νλ μ½λμ΄λ€. μ΄λ κ² νλ €λ©΄ κ°κ°μ νλͺ©μ MediaItem λΏλ§ μλλΌ Movie λ Song μΌλ‘μ¨ μ κ·Όν νμκ° μλ€. μ€λͺ μμ μ¬μ©ν Moiveλ Songμ directorλ artist μμ±μ μ κ·Όν μ μμΌλ €λ©΄ μ΄κ² νμνκΈ° λλ¬Έμ΄λ€.
μ΄ μμ μμλ κ° νλͺ©μ΄ Movie μ΄κ±°λ Song μ΄λ€. κ° νλͺ©μ΄ λμ§ λ―Έλ¦¬ μμμ μμλ μμΌλ―λ‘, as?λ₯Ό νμ©νλκ² μ’λ€.
λ§μ½ μ μ½λμμ itemμ Movieν΄λμ€ νμ μ ν¬ν¨νλ νμ μ΄ μλ€λ©΄, movie μμμ Movie ν΄λμ€ νμ μ΄ ν λΉλλ€. μ΄κ²μ΄ λ°λ‘ λ€μ΄μΊμ€ν μ΄λ€. μΊμ€ν μ μ€μ λ‘ μΈμ€ν΄μ€λ₯Ό μμ νκ±°λ κ°μ λ³κ²½νμ§λ μλλ€. μΈμ€ν΄μ€λ λμΌνκ² μ μ§λμ§λ§, μΊμ€νΈ λ νμ μ μΈμ€ν΄μ€λ‘ μ²λ¦¬λλ€.
Any, AnyObjectμ νμ μΊμ€ν
Swiftμμλ λ κ°μ§ νΉλ³ν νμ μ μ 곡νλ€.
- 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)" })
Any λ₯Ό μ¬μ©νμ¬ μλ‘λ€λ₯Έ νμ μ΄ μμΈ λ°°μ΄ thingsλ₯Ό μμ±νλ€.
thingsμ νμ μ Array<Any> μ΄κΈ° λλ¬Έμ μ΄λ¬ν κ²½μ° λͺ¨λ νλͺ©μ λνμ¬ νΉμ νμ μ μ°Ύκ³ μΆλ€λ©΄ switch λ¬Έ case μ μμ asλ is λ₯Ό μ¬μ©νμ¬ νμΈν μ μλ€.
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("and 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")
}
}
// zero as an Int
// zero as a Double
// an integer value of 42
// a positive double value of 3.14159
// a string value of "hello"
// an (x, y) point at 3.0, 5.0
// a movie called Ghostbusters, dir. Ivan Reitman
// Hello, Michael
μ μ½λμ²λΌ things μ λͺ¨λ νλͺ©μ μ κ·Όν λλ§λ€ switch λ¬ΈμΌλ‘ νμ μΊμ€νΈλ₯Ό μ§ννμ¬ μ±κ³΅ν μΌμ΄μ€μ μ½λλ₯Ό μ€ννκ² λλ€.
let optionalNumber: Int? = 3
things.append(optionalNumber) // Warning
things.append(optionalNumber as Any) // No warning
Anyνμ μ μ΅μ λ νμ μ ν¬ν¨ν λͺ¨λ νμ μ κ°μ λνλΈλ€. Swiftλ Any νμ μ κ°μΌλ‘ νΉμ νμ μ μ΅μ λ κ°μ μ¬μ©νλ €λ κ²½μ°μ κ²½κ³ λ₯Ό μ€λ€. μ μ½λμ²λΌ Int? νμ Any νμ μΌλ‘ μ¬μ©νλ©΄ μ€λ₯λ₯Ό λ°μμν¨λ€λ κ²μ΄λ€. μ΄λ κ² μ΅μ λ κ°μ Anyλ‘ μ¬μ©ν΄μΌνλ κ²½μ° as μ°μ°μλ₯Ό μ¬μ©νμ¬ νΉμ νμ μ μ΅μ λ κ°μ Anyλ‘ μΊμ€ν ν΄μ μ¬μ©ν μ μλ€.