타입 캐스팅

seocho·2022년 8월 31일
0

iOS

목록 보기
8/24

타입 캐스팅 (Type casting) 은 인스턴스의 타입을 확인하거나 해당 인스턴스를 자체 클래스 계층 구조의 다른 곳에서 다른 상위 클래스 또는 하위 클래스로 취급하는 방법입니다.

Swift에서 타입 캐스팅은 is 와 as 연산자로 구현됩니다. 이 두 연산자는 값의 타입을 확인하거나 값을 다른 타입으로 캐스트하는 간단하고 표현적인 방법을 제공합니다.

타입 검사

"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")
// Prints "Media library contains 2 movies and 3 songs"

다운 캐스팅

특정 클래스 타입의 상수 또는 변수는 하위 클래스의 인스턴스를 참조할 수 있습니다. 이것이 사실이라고 생각하는 경우 타입 캐스트 연산자 (type cast operator) (as? 또는 as!)를 사용하여 하위 클래스 타입으로 다운 캐스트 (downcast) 할 수 있습니다.

다운 캐스팅의 실패 경우를 감안해서 옵셔널 값을 반환할 수 있음

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에 대한 타입 캐스팅

Swift는 비특정 타입 작업을 위해 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 구문의 케이스로 is 또는 as 패턴을 사용할 수 있습니다. 아래의 예제는 things 배열에 항목을 반복하고 switch 구문으로 각 항목의 타입을 조회합니다. 몇몇의 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")
    }
}

// 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

Any 타입의 값이 기대되는 곳에 옵셔널 값을 사용했을 때

Any 타입은 옵셔널 타입을 포함하여 모든 타입의 값을 나타냅니다. Swift는 Any 타입의 값이 기대되는 곳에 옵셔널 값을 사용하면 경고를 줍니다. Any 값으로 옵셔널 값을 사용하는 것이 필요하다면 아래와 같이 as 연산자를 사용하여 명시적으로 옵셔널을 Any 로 캐스트 할 수 있습니다.

let optionalNumber: Int? = 3
things.append(optionalNumber)        // Warning
things.append(optionalNumber as Any) // No warning
profile
iOS 개린이

0개의 댓글