study record

[Swift] 타입 캐스팅 본문

Swift/스위프트 프로그래밍

[Swift] 타입 캐스팅

asong 2022. 1. 6. 00:13

*책 “스위프트 프로그래밍”을 학습하고 작성한 글입니다.

 

스위프트는 데이터 타입 안전을 위하여 각기 다른 타입끼리의 값 교환을 엄격히 제한한다.

 

기존 언어의 타입 변환과 스위프트의 타입 변환

// C 언어
double value = 3.3
int convertedValue = (int)value
convertedValue = 5.5  // double -> int 암시적 데이터 타입 변환

// swift 언어
var value: Double = 3.3
var convertedValue: Int = Int(value)
convertedValue = 5.5  //오류

 

스위프트 타입캐스팅

스위프트의 타입캐스팅은 인스턴스의 타입을 확인하거나 자신을 다른 타입의 인스턴스인양 행세할 수 있는 방법으로 사용할 수 있다. 스위프트의 타입캐스팅은 is와 as 연산자로 구현했다. 이 두 연산자로 값의 타입을 확인하거나 다른 타입으로 전환할 수 있다. 또한 타입캐스팅을 통해 프로토콜을 준수하는지도 확인해볼 수 있다.

스위프트의 타입캐스팅은 실제로 참조 타입에서 주로 사용된다.

 

데이터타입 확인

타입 확인 연산자인 is를 사용하여 인스턴스가 어떤 클래스의 인스턴스인지 타입을 확인해볼 수 있다. 타입 확인 연산자는 인스턴스가 해당 클래스의 인스턴스거나 그 자식클래스의 인스턴스라면 true를 반환하고, 그렇지 않다면 false를 반환한다. is 연산자는 클래스의 인스턴스 뿐만 아니라 모든 데이터 타입에 사용할 수 있다.

// 데이터 타입 확인
let coffee: Coffee = Coffee(shot: 1)

let myCoffee: Americano = Americano(shot: 2, iced: false)

let yourCoffee: Lattee = Latte(flavor: "green tea", shot: 3)

print(coffee is Coffee) // true
print(coffee is Americano) // false
print(coffee is Latte) //false

print(myCoffee is Coffee) // true
print(yourCoffee is Coffee) //true

print(myCoffee is Latte) // false
print(yourCoffee is Latte) // true

 

is 연산자 외에도 타입을 확인해볼 수 있는 방법은 메타 타입 타입을 이용하는 것이다.

메타 타입 타입은 타입의 타입을 뜻한다. 클래스 타입, 구조체 타입, 열거형 타입, 프로토콜 타입 등의 타입의 타입이다. 즉, 타입 자체가 하나의 타입으로 또 표현할 수 있다는 것이다.

클래스, 구조체, 열거형의 이름은 타입으 이름이다. 그 타입으 ㅣ이름 뒤에 .Type을 붙이면 이는 메타 타입을 나타낸다. 프로토콜 타입의 메타 타입은 .Protocol 이라고 붙여주면 된다.

또한 self를 사용해서 타입을 값처럼 표현할 수 있다. 예를 들어 SomeClass.self라고 표현하면 SomeClass의 인스턴스가 아니라 SomeClass 타입을 값으로 표현한 값을 반환한다.

 

다운캐스팅

어떤 클래스 타입의 변수 또는 상수가 해당 클래스의 인스턴스를 참조하지 않을 수도 있다. 다운캐스팅은 클래스의 상속 모식도에서 자식클래스보다 더 상위에 있는 부모클래스의 타입을 자식클래스의 타입으로 캐스팅한다고 해서 다운캐스팅이라고 부른다.

타입캐스트 연산자에는 as?와 as! 두 가지가 있다. 타입캐스트 연산자를 사용하여 자식클래스 타입으로 다운 캐스팅할 수 있다.

다운캐스팅은 실패의 여지가 충분히 있기 때문에 ?가 붙은 연산자와 !가 붙은 연산자 두 종류가 있다. 다운캐스팅을 시도해보는 조건부 연산자인 as?연산자는 다운캐스팅이 실패했을 경우 nil을 반환하고 다운캐스팅을 강제하는 as! 연산자는 다운캐스팅에 실패할 경우 런타임 오류가 발생한다. 따라서 as? 연산자는 반환 타입이 옵셔널이며 as! 연산자의 반환 타입은 옵셔널이 아니다.

컴파일러가 다운캐스팅을 확신할 수 있는 경우에는 as?나 as! 대신 as를 사용할 수도 있다. 항상 성공하는 것을 아는 경우는 캐스팅하려는 타입이 같은 타입이거나 부모클래스 타입이라는 것을 알 때이다.

Any, AnyObject와 타입캐스팅

스위프트에는 특정 타입을 지정하지 않고 여러 타입의 값을 할당할 수 있는 Any와 AnyObject 타입이 있다. Any는 함수 타입을 포함한 모든 타입을 뜻하고, AnyObject는 클래스 타입만을 뜻한다. Any, AnyObject를 사용하면 예기치 못한 오류가 발생할 확률이 높아지므로 되도록이면 사용을 지양하는 것이 좋다.

반환되는 타입이 Any, AnyObject라면 전달받은 데이터가 어떤 타입인지 확인하고 사용해야 한다.

'Swift > 스위프트 프로그래밍' 카테고리의 다른 글

[Swift] 익스텐션  (0) 2022.01.12
[Swift] 프로토콜  (0) 2022.01.11
[Swift] 상속  (0) 2021.12.27
[Swift] 서브스크립트  (0) 2021.12.26
[Swift] 모나드  (0) 2021.12.06