타입 캐스팅은 인스턴스의 타입을 확인하거나 클래스 계층의 다른 부모 클래스/자식 클래스로 취급하는 방법이다.
Swift의 타입 캐스팅은 is 나 as 연산자로 구현된다. 이 두 연산자는 값의 타입을 확인하거나 다른 타입으로 바꾸는 간단하고
표현적인 방법을 제공한다.
타입 확인 연산자 is
- 해당 클래스이거나 자식 클래스라면 true 아니면 false를 반환한다.
- 클래스뿐 아니라 모든 데이터 타입에 사용가능하다.
class Fruits {
var name: String
init(name: String) {
self.name = name
}
}
var apple = Fruits(name: "Apple")
// Fruits 클래스의 인스턴스 타입인지 확인
if apple is Fruits {
print(true) // true
}
// String 타입인지 확인
if apple is String {
print(true) // true
}
Downcasting (다운캐스팅)
: 부모클래스에서 자식클래스로 형변환하는 것을 말하는데, 자식클래스의 프로퍼티와 메소드를 사용하기 위함이다.
다운 캐스팅에는 2가지 연산자가 존재한다.
- as? (옵셔널 캐스팅) : 변환이 성공하면 Optional 값을 가지며, 실패 시에는 nil 반환.
- as! (강제 캐스팅) : 변환이 성공하면 unwraping된 값을 가지며, 실패시 런타임 에러 발생.
* unwraping? :
class Shape {
var color = UIColor.yellow
func draw() {
print("draw shape")
}
}
class Rectangle: Shape {
var cornerRadius = 5.0
override func draw() {
print("draw rect")
}
}
class Triangle: Shape {
override func draw() {
print("draw triangle")
}
}
let shape: Shape = Rectangle()
type(of: shape) //Rectangle.Type
let rect: Shape = Rectangle()
let tri: Shape = Triangle()
if let rect = rect as? Rectangle {
rect.cornerRadius
} else {
print("downcasting fail")
}
if let tri = tri as? Triangle {
tri.draw()
} else {
print("downcasting fail")
}
Upcasting(업캐스팅)
: 자식클래스에서 부모클래스로 형변환 하는것을 말하며, 부모클래스의 프로퍼티와 메소드를 사용하기 위함이다.
- as : 타입 변환이 확실하게 가능한 경우(업캐스팅, 자기 자신 등) 에만 사용 가능함. 그 외에는 컴파일 에러.
let shape: Shape = Shape()
let rectangle: Shape = Rectangle()
let rectangle2: Shape = Rectangle() as Shape
let triangle: Shape = Triangle()
let triangle2: Shape = Triangle() as Shape
rectangle2.color
rectangle2.draw()
-> Rectangle의 cornerRadius 프로퍼티가 있음에도 불구하고, upcasting 성공 시 Shape(부모)의 프로퍼티와 메서드만 보여지는 것을
알수 있다.
Any, AnyObject
Swift는 두 가지의 특별한 비지정 타입을 제공한다.
- Any : 함수타입을 포함하여 모든 타입의 인스턴스를 대표한다.
- AnyObject : 모든 클래스 타입을 대표한다.
꼭 필요할 때만 Any와 AnyObject를 사용한다. 코드에서 작동할 것이라 예상하는 타입을 지정하는 것이 항상 좋다.
다음은 여러 타입이 섞여 있는 작업을 하기 위해 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)" })
Any 또는 AnyObject로만 알려진 상수나 변수의 타입을 확인하기 위해 switch문의 케이스에서 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")
}
}
// 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
출처 : https://jinnify.tistory.com/16
'iOS > Swift' 카테고리의 다른 글
UIWebView 와 WKWebView 차이 (0) | 2021.12.12 |
---|---|
[Swift] Array, Dictionary, Set, Tuple (0) | 2021.12.12 |
[Swift] 메모리를 참조하는 방법 (Strong, Weak, Unowned) (1) | 2020.07.30 |
[Swift] Closure (0) | 2020.07.29 |
[Swift] Class 와 Struct (0) | 2020.07.03 |