- Reference
- https://docs.swift.org/swift-book/LanguageGuide/TypeCasting.html
Type Casting — The Swift Programming Language (Swift 5.6)
Type Casting Type casting is a way to check the type of an instance, or to treat that instance as a different superclass or subclass from somewhere else in its own class hierarchy. Type casting in Swift is implemented with the is and as operators. These tw
docs.swift.org
[카테고리]
- Defining a Class Hierarchy for Type Casting
- Checking Type
- Downcasting
- Type Casting for Any and AnyObject
[정의]
타입 캐스팅은 인스턴스의 타입을 확인하는 방법이다.
또는 인스턴스를 자체 클래스 계층구조의 다른 위치에서 다른 수퍼 클래스 or 하위 클래스로 취급한다.
[표현방법]
is, as
유형 캐스팅은 is 및 as 연산자로 구현되며 값의 유형을 확인하거나 다른 유형으로 캐스팅하는 간단한 표현방법이다.
[특징]
- 프로토콜을 준수하는지 여부를 확인할 수도 있다.
- 캐스팅은 실제로 인스턴스를 수정하거나 값을 변경하지 않는다. 기본 인스턴스는 동일하게 유지됩니다. 단순히 캐스트된 유형의 인스턴스로 처리되고 엑세스 됩니다.
# 유형 캐스팅을 위한 class 계층 정의
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: "기생충", director: "봉준호"),
Song(name: "Y", artist: "지코"),
Movie(name: "스타이즈본", director: "브래들리쿠퍼"),
Song(name: "Counting Start", artist: "비오"),
Song(name: "V", artist: "박재범")
]
[library인스턴스 설명]
현재는 상속받은 MediaItem유형으로 지정이되어있지만 이 배열의 내용은 반복하는 경우 다시받는 항목은
Movie or Song이 아닌 MediaItem으로 유형이 지정된다.
이를 기본유형으로 사용하려면 아래에 설명된대로 유형을 확인하거나 다른 유형으로 다운캐스트를 해야한다.
# Check Type
[사용방법]
is 를 사용하여 인스턴스가 특정 하위 클래스 유형인지 여부를 확인한다.
인스턴스가 하위클래스이면 true, 그렇지 않으면 false를 반환한다.
var movieCount = 0
var songCount = 0
for item in library {
if item is Movie {
movieCount += 1
print(item.name)
} else if item is Song {
songCount += 1
print(item.name)
}
}
print("영화 수: \(movieCount) 노래 수: \(songCount)")
[궁금한점]
- 위 반복문에서 item is Movie일경우 item.name을 출력할 수 있지만 director는 출력할 수 없다.
그 이유는 뭘까 ?
# DownCasting
[정의]
특정 클래스 유형의 상수 또는 변수는 실제로 배후에서 하위 클래스의 인스턴스를 참조할 수 있다.
이것이 사실이라고 생각되는 경우 연산자 as? as!를 사용하여 캐스팅할 수 있다.
- 다운캐스팅이 실패할 수 있으므로 두가지 다른 형식으로 제공된다.
- as?는 다운캐스팅에 성공할 경우 선택적으로 값을 반환하고 아닐경우 nil을 반환
- as!는 강제로 해제한다. 고로 확신할수없는경우 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.director의 값을 읽어올 수 없다.
그래서 as?를 지우게되면 director라는 멤버를 가지고있지않다고 컴파일 에러가난다.
[다운캐스팅]
상위 클래스인 MediaItem타입으로 초기화되어있는 library는 하위 클래스로 무작정 접근할 수는 없고 값에 접근하려면
다운 캐스팅을 시도하여 접근할 수 있다.
library의 item요소는 MediaItem요소이며 값이 Movie타입일 수도있고 Song타입일 수도 있다. 이런경우에는
as?를 사용하여 선택적인 값을 반환한다.
# Type Casting for Any and AnyObject
- 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)" })
for thing in things {
switch thing {
case 0 as Int:
print("zero as an Int")
case 0 as Double:
print("zero as an 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")
}
}
let optionalNumbner: Int? = 3
things.append(optionalNumbner)
things.append(optionalNumbner as Any)
print(things[8])
'문법' 카테고리의 다른 글
[Swift] Sequence Type이란? (0) | 2022.03.25 |
---|---|
[Swift] Class와 struct 중 어느것을 선택해야할까 ? (0) | 2022.02.22 |
[Swift] Error Handling[1편] 알아보자! (0) | 2022.02.19 |
[Swift] Set(집합)과 메서드기능을 알아보자!(feat. HashValue) (0) | 2022.02.09 |
[작성중...] What is the Mutating ? (0) | 2022.02.07 |