[Swift๐ฆฉ] #19 ํ์ ์บ์คํ #20 ์ค์ฒฉ๋ ํ์
Type Casting
- ์ธ์คํด์ค์ ํ์
์ ํ์ธํ๊ฑฐ๋
- ํด๋น ์ธ์คํด์ค๋ฅผ ๋ค๋ฅธ ์์ ํด๋์ค or ํ์ ํด๋์ค๋ก ์ทจ๊ธํ๋ ๋ฐฉ๋ฒ
- is,- as์ฐ์ฐ์๋ก ๊ตฌํ๋๋ค.
- ํ๋กํ ์ฝ์ ์ค์ํ๋์ง๋ ํ์ธํ  ์ ์์.
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)
    }
}
// MediaType ๊ณผ ๊ทธ๊ฑธ ์์ํ Movie, Song ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๊ธฐ ๋๋ฌธ์
// [MediaType] ์ผ๋ก ์ถ๋ก ๋จ.
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")
]1. ํ์ ๊ฒ์ฌ
- is๋ก ํด๋น ์ธ์คํด์ค๊ฐ ํ์ ํด๋์ค ํ์ ์ด๋ฉด true ์๋๋ฉด false
- ์ ๋ง ๊ทธ ํ์ ์ธ์ง ํ์ธ๋ง ํ์ํ ๋ ์ฌ์ฉ.
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")
// Prints "Media library contains 2 movies and 3 songs"2. ๋ค์ด์บ์คํ
- ํน์  ํด๋์ค ํ์ ์ ์์/๋ณ์๋ ํ์ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ ์ ์๋ค๊ณ ํ์ ๋๋ ๊ฒฝ์ฐ,
- as?- as!๋ฅผ ์ด์ฉํด์ ํ์ ํด๋์ค ํ์ ์ผ๋ก ๋ค์ด์บ์คํธ ํ ์ ์๋ค.
- ์คํจ๊ฐ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์, Optional ๊ฐ์ ๋ฐํํ๋ ? ๊ณผ ๊ฐ์ ๋ก ๋ค์ด์บ์คํธ ํ๋ !
for item in library {
    // ํ์ ํ์
์ด์ด์ผ movie.director, song.artist ์ ์ ๊ทผํ  ์ ์๋ค.
    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)")
    }
}3. Any, AnyObject ์ ๋ํ ํ์ ์บ์คํ
- ํน์ ๋์ง ์์ ํ์
์ ์ํด์- Any: ํจ์ ํ์ ์ ํฌํจํ ๋ชจ๋ ํ์ ์ ์ธ์คํด์ค๋ฅผ ๋ํ๋ผ ์ ์์.
- AnyObject: ๋ชจ๋ ํด๋์ค ํ์ ์ ์ธ์คํด์ค๋ฅผ ๋ํ๋ผ ์ ์์.
 
- ๋๊ฐ์ง ํ์ ์ ์ ๊ณตํ๋ค.
- optional ๊ฐ์ Any ๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ as Any๋ก ์บ์คํธํ์.
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)" })
let optionalNumber: Int? = 3
things.append(optionalNumber as Any) // optional ๊ฐ์ ๋ฃ์ผ๋ ค๋ฉด Any ๋ก ์บ์คํธํ์.
// switch ๊ตฌ๋ฌธ์ ํตํด์ ํ์ธํ  ์ ์๋ค.
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")
    }
}Nested Types
- ๋ณต์กํ ํ์
์ ์ปจํ
์คํธ ๋ด์์ ์ฌ์ฉํ๊ธฐ ์ํด struct, class, enum ์์ ์ค์ฒฉํ์ฌ struct, class, enum ์ ์ ์ธํ  ์ ์๋ค.
- ํ์ํ ๋งํผ ์ค์ฒฉํ  ์ ์๋ค.
1. ๋์
struct BlackjackCard > enum Suit
struct BlackjackCard > enum Rank > struct Values
struct BlackjackCard {
    // nested Suit enumeration
    enum Suit: Character {
        case spades = "โ ", hearts = "โก", diamonds = "โข", clubs = "โฃ"
    }
    // nested Rank enumeration
    enum Rank: Int {
        case two = 2, three, four, five, six, seven, eight, nine, ten
        case jack, queen, king, ace
        struct Values {
            let first: Int, second: Int?
        }
        var values: Values {
            switch self {
            case .ace:
                return Values(first: 1, second: 11)
            case .jack, .queen, .king:
                return Values(first: 10, second: nil)
            default:
                return Values(first: self.rawValue, second: nil)
            }
        }
    }
    // BlackjackCard properties and methods
    let rank: Rank, suit: Suit
    var description: String {
        var output = "suit is \(suit.rawValue),"
        output += " value is \(rank.values.first)"
        if let second = rank.values.second {
            output += " or \(second)"
        }
        return output
    }
}์ง์ ๋ init์ด ์๊ธฐ ๋๋ฌธ์ ๋ฉค๋ฒ๋ณ ์ด๊ธฐ์ ์ฌ์ฉ ๊ฐ๋ฅ.
let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
// Prints "theAceOfSpades: suit is โ , value is 1 or 11"2. ์ฐธ์กฐ
์ค์ฒฉ๋ ํ์ ์ ์ด๋ฆ์ chaining ์ฒ๋ผ . ์ ๋ถ์ฌ์ ์ฐธ์กฐํ ์ ์๋ค.
let heartsSymbol = BlackjackCard.Suit.hearts.rawValue
// heartsSymbol is "โก"Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ([Swift๐ฆฉ] #19 ํ์ ์บ์คํ #20 ์ค์ฒฉ๋ ํ์ ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@ddosang/Swift-19-ํ์ -์บ์คํ -20-์ค์ฒฉ๋-ํ์์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
                                
                                
                                
                                
                                
                                ์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ  ๋ฐ๊ฒฌ์ ์ ๋
                                (Collection and Share based on the CC Protocol.)
                            
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค