티스토리 뷰

출처

http://kka7.tistory.com/24




타입 변환 (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")

]




타입 확인하기

해당 인스턴스가 클래스의 타입인지 확인하기 위해서는
is 키워드를 사용한다.

var movieCount = 0

var songCount = 0

var mediaCount = 0


for item in library {

    if item is Movie {

        movieCount += 1

    } else if item is Song {

        songCount += 1

    } else if item is MediaItem {

        mediaCount += 1

    }

}


print("movieCount : \(movieCount) / songCount : \(songCount) / mediaCount : \(mediaCount)")

//movieCount : 2 / songCount : 3 / mediaCount : 0




다운캐스팅 (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)")

    }

}







Any 와 AnyObject 에 대한 타입 캐스팅

지정되지 않은 타입의 작업 시 2개의 특별한 타입을 사용할 수 있다.

- 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 또는 AnyObject 타입으로 된 상수와 변수의 특정 타입을 발견하기 위해
switch 문의 cases 에서 is 또는 as 패턴을 사용할 수 있다.

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 의 값이 예상되는 곳에 옵셔널 값을 사용하면 경고를 한다.
옵셔널 값을 Any 값으로 사용하는게 정말 필요하다면
명시적인 변환을 위해 as 연산자를 사용할 수 있다.

let optionalNumber: Int? = 3

things.append(optionalNumber)        // Warning

things.append(optionalNumber as Any) // No warning







공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함