You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
타입 캐스팅(type casting)은 인스턴스의 타입을 확인하거나 클래스 계층의 다른 부모 클래스 / 자식 클래스로 취급하는 방법이다
Swift의 타입 캐스팅은 is와 as 연산자를 사용하여 구현된다
두 연산자는 값의 타입을 확인하거나 다른 타입에 값을 캐스팅할 수 있는 간단하고 표현적인 방법을 제공한다
또한, 타입 캐스팅을 사용하여 Checking for Protocol Conformance에서 설명된 대로 타입이 프로토콜을 준수하는지 여부를 확인할 수 있다
타입 캐스팅을 위한 클래스 계층 선언
클래스 및 자식 클래스 계층과 함께 타입 캐스팅을 사용하여
특정 클래스 인스턴스의 유형을 확인하고
동일한 계층 내의 다른 클래스로 해당 인스턴스를 캐스팅할 수 있다
아래 세 가지 코드는 클래스 계층과 이 클래스 인스턴스를 포함하는 배열을 정의한다
첫 번째로 MediaItem 기반 클래스를 정의한다. String 타입의 name 프로퍼티와 init(name:) 이니셜라이저를 선언한다.
classMediaItem{varname:Stringinit(name:String){self.name = name
}}
다음으로 MediaItem의 두 가지 자식 클래스를 정의한다
Movie와 Song은 영화 / 음악에 대한 추가적인 정보를 캡슐화한다
Movie 클래스는 기본 MediaItem 클래스 위에 director 프로퍼티와 이니셜라이저를 추가한다
Song 클래스는 기본 MediaItem 클래스 위에 artist 프로퍼티와 이니셜라이저를 추가한다
classMovie:MediaItem{vardirector:Stringinit(name:String, director:String){self.director = director
super.init(name: name)}}classSong:MediaItem{varartist:Stringinit(name:String, artist:String){self.artist = artist
super.init(name: name)}}
마지막으로 Movie 인스턴스와 Song 인스턴스를 저장하는 library 상수 배열을 만든다
library 배열의 타입은 배열 리터럴의 내용으로 초기화하면서 추론된다
Swift의 타입 체커는 Movie와 Song이 같은 부모 클래스 MediaItem을 갖는다고 추론할 수 있다
따라서 library 배열은 [MediaItem] 타입을 갖게 된다
letlibrary=[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")]// the type of "library" is inferred to be [MediaItem]
library 배열은 Movie와 Song 인스턴스를 저장한다
하지만, 배열의 내용을 순회할 때 반환되는 아이템의 타입은 MediaItem이 된다
때문에 타입을 확인하고 서로 다른 타입으로 다운캐스트(downcast) 해야 한다
타입 확인하기
타입 확인 연산자 is를 사용해 인스턴스가 특정 자식 클래스 타입인지 확인한다
타입 확인 연산자는 그 자식 클래스의 인스턴스면 true를, 아니면 false를 반환한다
아래 예시는 Movie 인스턴스와 Song 인스턴스의 개수를 세는 movieCount와 songCount 두 변수를 정의한다
varmovieCount=0varsongCount=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"
해당 예제는 library 배열의 모든 항목을 순회한다
각 경로에서 for-in 루프는 배열의 다음 MediaItem으로 item 상수를 설정한다
item is Movie는 현재 MediaItem이 Movie 인스턴스이면 true를 반환하고 그렇지 않으면 false를 반환한다
마찬가지로 item is Song은 항목이 Song 인스턴스인지 확인한다
for-in 루프가 끝날 때 movieCount 및 songCount 값은 각각의 유형에 대해 발견된 MediaItem 인스턴스의 수를 나타 낸다
다운캐스팅 (Downcasting)
특정 클래스 타입의 상수나 변수는 자식 클래스의 인스턴스를 참조하고 있을 수 있다
타입 변환 연산자 as?와 as!를 사용해 자식 클래스로 다운캐스트 할 수 있다
다운캐스팅은 실패할 수 있기 때문에 타입 변환 연산자는 두 가지 형태를 지닌다
조건적 형태 as?는 다운캐스팅을 시도한 타입의 옵셔널 값을 반환한다
강제적 형태 as!는 다운캐스트를 시도하고 결과를 단일 복합 작업으로 강제 언래핑한다
다운캐스트가 성공한다는 보장이 없을 때 as?를 사용한다
해당 형태의 연산자는 항상 옵셔널 값을 반환하고,
다운캐스트가 불가능하면 값은 nil이 된다
이렇게 하면 다운캐스트가 성공했는지 확인할 수 있다
다운캐스트가 항상 성공한다는 확신이 있을 때 as!를 사용한다
해당 형태의 연산자는 다운 캐스트가 실패하면 런타임 에러를 발생시킨다
아래 예시는 library의 각 MediaItem을 순회하고 항목에 대한 적절한 설명을 문자열로 print한다
이를 위해 Movie나 Song으로 접근해야만 한다
print에서 director와 artist 프로퍼티에 접근할 필요성이 생기기 때문이다
배열의 각 아이템이 Movie인지 Song인지 확신할 수 없기 때문에 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
캐스팅은 인스턴스를 수정하거나 값을 바꿀 수 없다
기저의 인스턴스는 동일하게 유지된다
변환을 시도한 타입의 인스턴스로써 간단히 취급하고 접근하는 것
예제는 현재 item을 Movie로 다운캐스트하는 것으로 시작한다
항목이 MediaItem 인스턴스이기 때문에 Movie가 될 수 있으며,
마찬가지로 Song이 될 수도, 2가지에 속하지 않는 MediaItem일 수도 있다
이러한 불확실성으로 인해 as? 타입 캐스팅 연산자는 자식 클래스 형식으로 다운캐스트할 때 옵셔널 값을 반환한다
item as? Movie의 결과는 Movie? 또는 "optional Movie" 유형이다
library 배열의 Song 인스턴스에 적용하면 Movie로 다운캐스팅이 실패한다
문제를 해결하기 위해 예제에서는 if let 옵셔널 바인딩을 사용하여
Movie?에 실제로 값이 포함되어 있는지 확인한다 - 다운캐스트 성공 여부 확인
이 옵셔널 바인딩은 "if let movie = item as? Movie"는 다음과 같이 읽을 수 있다
"Movie로 간주하여 item에 접근해보고 작업이 성공하면, 반환된 옵셔널한 Movie 타입의 값을 movie 새 임시 상수에 설정하자"
다운캐스팅이 성공하면 Movie의 프로퍼티를 사용하여 해당 Movie 인스턴스에 대한 설명(movie.director)을 print 한다
동일한 원칙은 Song 인스턴스를 확인하는데도 마찬가지로 적용되어,
Song이 library에서 발견될 때마다 Song 인스턴스에 대한 설명(song.artist)을 print하는 데 사용된다
타입 캐스팅은 실제로 인스턴스를 수정하거나 인스턴스 값을 변경하지 않는다
기본 인스턴스는 그대로 유지되며, 단순히 해당 인스턴스가 캐스팅된 유형의 인스턴스로 처리되고 접근 가능하게 된다
Any와 AnyObject를 위한 타입 캐스팅
Swift는 두 가지의 특별한 비지정 타입을 제공한다
Any는 함수 타입을 포함하여 모든 타입의 인스턴스를 대표한다
AnyObject는 모든 클래스 타입을 대표한다
제공되는 동작과 기능이 명시적으로 필요한 경우에만 Any와 AnyObject를 사용한다
코드에서 작동할 것이라 예상하는 타입을 항상 구체적으로 지정하는 것이 좋다
다음은 함수 타입 및 클래스가 아닌 타입을 포함한 다양한 타입이 섞여 있는 작업을 하기 위해 Any를 사용하는 예시를 보여 준다
예제에서는 Any 타입의 값을 저장할 수 있는 things라는 배열을 생성한다
things 배열에는 두 개의 Int 값, 두 개의 Double 값, 한 개의 String 값, 한 종류의 튜플(Double, Double),
Movie "Ghostbusters" 및 String 값을 가져와서 다른 String 값을 반환하는 클로저가 포함된다
Any 또는 AnyObject로만 알려진 상수나 변수의 타입을 확인하기 위해
is 또는 as 패턴을 switch 문에 사용할 수 있다
아래 예제는 things 배열의 항목을 순회하고 switch 문을 사용하여 각 항목의 타입을 쿼리한다
switch 문의 몇 가지 경우는 일치하는 값을 지정된 타입의 상수에 바인딩하여 값을 print할 수 있도록 한다
for thing in things {
switch thing {case0asInt:print("zero as an Int")case0asDouble:print("zero as a Double")caseletsomeInt as Int:print("an integer value of \(someInt)")caseletsomeDouble as Doublewhere someDouble >0:print("a positive double value of \(someDouble)")case is Double:print("some other double value that I don't want to print")caseletsomeString as String:print("a string value of \"\(someString)\"")caselet(x, y) as (Double,Double):print("an (x, y) point at \(x), \(y)")caseletmovie as Movie:print("a movie called \(movie.name), dir. \(movie.director)")caseletstringConverter 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는 옵셔널 타입을 포함한 모든 타입의 값을 나타낸다
Swift는 Any가 예상되는 값에 옵셔널 값을 사용할 경우 경고를 표시한다
만약 Any 값에 정말 옵셔널을 사용하길 원한다면 옵셔널을 Any로 명시적으로 변환하기 위해 as 연산자를 사용할 수 있다
letoptionalNumber:Int?=3
things.append(optionalNumber)// Warning
things.append(optionalNumber asAny)// No warning
The text was updated successfully, but these errors were encountered:
타입 캐스팅(type casting)은 인스턴스의 타입을 확인하거나 클래스 계층의 다른 부모 클래스 / 자식 클래스로 취급하는 방법이다
Swift의 타입 캐스팅은 is와 as 연산자를 사용하여 구현된다
두 연산자는 값의 타입을 확인하거나 다른 타입에 값을 캐스팅할 수 있는 간단하고 표현적인 방법을 제공한다
또한, 타입 캐스팅을 사용하여 Checking for Protocol Conformance에서 설명된 대로 타입이 프로토콜을 준수하는지 여부를 확인할 수 있다
타입 캐스팅을 위한 클래스 계층 선언
클래스 및 자식 클래스 계층과 함께 타입 캐스팅을 사용하여
특정 클래스 인스턴스의 유형을 확인하고
동일한 계층 내의 다른 클래스로 해당 인스턴스를 캐스팅할 수 있다
아래 세 가지 코드는 클래스 계층과 이 클래스 인스턴스를 포함하는 배열을 정의한다
첫 번째로 MediaItem 기반 클래스를 정의한다. String 타입의 name 프로퍼티와 init(name:) 이니셜라이저를 선언한다.
다음으로 MediaItem의 두 가지 자식 클래스를 정의한다
Movie와 Song은 영화 / 음악에 대한 추가적인 정보를 캡슐화한다
Movie 클래스는 기본 MediaItem 클래스 위에 director 프로퍼티와 이니셜라이저를 추가한다
Song 클래스는 기본 MediaItem 클래스 위에 artist 프로퍼티와 이니셜라이저를 추가한다
마지막으로 Movie 인스턴스와 Song 인스턴스를 저장하는 library 상수 배열을 만든다
library 배열의 타입은 배열 리터럴의 내용으로 초기화하면서 추론된다
Swift의 타입 체커는 Movie와 Song이 같은 부모 클래스 MediaItem을 갖는다고 추론할 수 있다
따라서 library 배열은 [MediaItem] 타입을 갖게 된다
library 배열은 Movie와 Song 인스턴스를 저장한다
하지만, 배열의 내용을 순회할 때 반환되는 아이템의 타입은 MediaItem이 된다
때문에 타입을 확인하고 서로 다른 타입으로 다운캐스트(downcast) 해야 한다
타입 확인하기
타입 확인 연산자 is를 사용해 인스턴스가 특정 자식 클래스 타입인지 확인한다
타입 확인 연산자는 그 자식 클래스의 인스턴스면 true를, 아니면 false를 반환한다
아래 예시는 Movie 인스턴스와 Song 인스턴스의 개수를 세는 movieCount와 songCount 두 변수를 정의한다
해당 예제는 library 배열의 모든 항목을 순회한다
각 경로에서 for-in 루프는 배열의 다음 MediaItem으로 item 상수를 설정한다
item is Movie는 현재 MediaItem이 Movie 인스턴스이면 true를 반환하고 그렇지 않으면 false를 반환한다
마찬가지로 item is Song은 항목이 Song 인스턴스인지 확인한다
for-in 루프가 끝날 때 movieCount 및 songCount 값은 각각의 유형에 대해 발견된 MediaItem 인스턴스의 수를 나타 낸다
다운캐스팅 (Downcasting)
특정 클래스 타입의 상수나 변수는 자식 클래스의 인스턴스를 참조하고 있을 수 있다
타입 변환 연산자 as?와 as!를 사용해 자식 클래스로 다운캐스트 할 수 있다
다운캐스팅은 실패할 수 있기 때문에 타입 변환 연산자는 두 가지 형태를 지닌다
조건적 형태 as?는 다운캐스팅을 시도한 타입의 옵셔널 값을 반환한다
강제적 형태 as!는 다운캐스트를 시도하고 결과를 단일 복합 작업으로 강제 언래핑한다
다운캐스트가 성공한다는 보장이 없을 때 as?를 사용한다
해당 형태의 연산자는 항상 옵셔널 값을 반환하고,
다운캐스트가 불가능하면 값은 nil이 된다
이렇게 하면 다운캐스트가 성공했는지 확인할 수 있다
다운캐스트가 항상 성공한다는 확신이 있을 때 as!를 사용한다
해당 형태의 연산자는 다운 캐스트가 실패하면 런타임 에러를 발생시킨다
아래 예시는 library의 각 MediaItem을 순회하고 항목에 대한 적절한 설명을 문자열로 print한다
이를 위해 Movie나 Song으로 접근해야만 한다
print에서 director와 artist 프로퍼티에 접근할 필요성이 생기기 때문이다
배열의 각 아이템이 Movie인지 Song인지 확신할 수 없기 때문에 as?를 사용해 다운캐스트하는 것이 적절하다
캐스팅은 인스턴스를 수정하거나 값을 바꿀 수 없다
기저의 인스턴스는 동일하게 유지된다
변환을 시도한 타입의 인스턴스로써 간단히 취급하고 접근하는 것
예제는 현재 item을 Movie로 다운캐스트하는 것으로 시작한다
항목이 MediaItem 인스턴스이기 때문에 Movie가 될 수 있으며,
마찬가지로 Song이 될 수도, 2가지에 속하지 않는 MediaItem일 수도 있다
이러한 불확실성으로 인해 as? 타입 캐스팅 연산자는 자식 클래스 형식으로 다운캐스트할 때 옵셔널 값을 반환한다
item as? Movie의 결과는 Movie? 또는 "optional Movie" 유형이다
library 배열의 Song 인스턴스에 적용하면 Movie로 다운캐스팅이 실패한다
문제를 해결하기 위해 예제에서는 if let 옵셔널 바인딩을 사용하여
Movie?에 실제로 값이 포함되어 있는지 확인한다 - 다운캐스트 성공 여부 확인
이 옵셔널 바인딩은 "if let movie = item as? Movie"는 다음과 같이 읽을 수 있다
"Movie로 간주하여 item에 접근해보고 작업이 성공하면, 반환된 옵셔널한 Movie 타입의 값을 movie 새 임시 상수에 설정하자"
다운캐스팅이 성공하면 Movie의 프로퍼티를 사용하여 해당 Movie 인스턴스에 대한 설명(movie.director)을 print 한다
동일한 원칙은 Song 인스턴스를 확인하는데도 마찬가지로 적용되어,
Song이 library에서 발견될 때마다 Song 인스턴스에 대한 설명(song.artist)을 print하는 데 사용된다
Any와 AnyObject를 위한 타입 캐스팅
Swift는 두 가지의 특별한 비지정 타입을 제공한다
Any는 함수 타입을 포함하여 모든 타입의 인스턴스를 대표한다
AnyObject는 모든 클래스 타입을 대표한다
제공되는 동작과 기능이 명시적으로 필요한 경우에만 Any와 AnyObject를 사용한다
코드에서 작동할 것이라 예상하는 타입을 항상 구체적으로 지정하는 것이 좋다
다음은 함수 타입 및 클래스가 아닌 타입을 포함한 다양한 타입이 섞여 있는 작업을 하기 위해 Any를 사용하는 예시를 보여 준다
예제에서는 Any 타입의 값을 저장할 수 있는 things라는 배열을 생성한다
things 배열에는 두 개의 Int 값, 두 개의 Double 값, 한 개의 String 값, 한 종류의 튜플(Double, Double),
Movie "Ghostbusters" 및 String 값을 가져와서 다른 String 값을 반환하는 클로저가 포함된다
Any 또는 AnyObject로만 알려진 상수나 변수의 타입을 확인하기 위해
is 또는 as 패턴을 switch 문에 사용할 수 있다
아래 예제는 things 배열의 항목을 순회하고 switch 문을 사용하여 각 항목의 타입을 쿼리한다
switch 문의 몇 가지 경우는 일치하는 값을 지정된 타입의 상수에 바인딩하여 값을 print할 수 있도록 한다
The text was updated successfully, but these errors were encountered: