본 내용은 '스위프트 프로그래밍' 책을 학습한 후 이를 바탕으로 작성한 글입니다.
is
와 as
연산자로 구현한다.is
연산자is
를 사용하여 인스턴스가 어떤 클래스의 인스턴스인지 타입을 확인해볼 수 있다.true
를 반환하고, 그렇지 않다면 false
를 반환한다.is
연산자는 클래스의 인스턴스뿐만 아니라 모든 데이터 타입에 사용할 수 있다.class Coffee {
let name: String
let shot: Int
var description: String {
return "\(shot) shot \(name)"
}
init(shot: Int) {
self.shot = shot
self.name = "coffee"
}
}
class Americano: Coffee {
let iced: Bool
override var description: String {
return "\(shot) shot \(iced ? "iced" : "hot") americano"
}
init(shot: Int, iced: Bool) {
self.iced = iced
super.init(shot: shot)
}
}
let coffee: Coffee = Coffee(shot: 1)
print(coffee.description) //1 shot coffee
let americano: Americano = Americano(shot: 2, iced: true)
print(americano.description) //2 shot iced americano
print(coffee is Coffee) //true
print(coffee is Americano) //false
print(americano is Coffee) //true
print(americano is Americano) //true
.Type
을 붙이면 메타 타입을 나타낸다.protocol SomeProtocol { }
class SomeClass: SomeProtocol { }
let intType: Int.Type = Int.self
let stringType: String.Type = String.self
let classType: SomeClass.Type = SomeClass.self
let protocolType: SomeProtocol.Protocol = SomeProtocol.self
var someType: Any.Type
someType = intType
print(someType) //Int
someType = stringType
print(someType) //String
someType = classType
print(classType) //SomeClass
someType = protocolType
print(protocolType) //SomeProtocol
as?
와 as!
가 있다.as?
연산자는 다운캐스팅이 실패했을 경우 nil
을 반환하고, 다운캐스팅을 강제하는 as!
연산자는 다운캐스팅에 실패했을 경우 런타임 오류가 발생한다.class Coffee {
let name: String
let shot: Int
var description: String {
return "\(shot) shot \(name)"
}
init(shot: Int) {
self.shot = shot
self.name = "coffee"
}
}
class Americano: Coffee {
let iced: Bool
override var description: String {
return "\(shot) shot \(iced ? "iced" : "hot") americano"
}
init(shot: Int, iced: Bool) {
self.iced = iced
super.init(shot: shot)
}
}
let coffee: Coffee = Coffee(shot: 1)
let americano: Americano = Americano(shot: 2, iced: true)
if let actingOne: Americano = coffee as? Americano {
print("This is Americano")
} else {
print(coffee.description)
}
//1 shot coffee
if let actingOne: Coffee = coffee as? Coffee {
print("This is just coffee")
} else {
print(coffee.description)
}
//This is just coffee
if let actingOne: Americano = americano as? Americano {
print("This is Americano")
} else {
print(coffee.description)
}
//This is Americano
if let actingOne: Coffee = americano as? Coffee {
print("This is just coffee")
} else {
print(coffee.description)
}
//This is just coffee
Any
는 함수 타입을 포함한 모든 타입을 뜻하고, AnyObject
는 클래스 타입만을 뜻한다.Any
와 AnyObject
를 사용하면 예기치 못한 오류가 발생할 확률이 높아지므로 사용을 지양하는 것이 좋다.func checkAnyType(of item: Any) {
switch item {
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:
print("a positive double value of \(someDouble)")
case let someString as String:
print("a string value of \"\(someString)\"")
case let stringConverter as (String) -> String:
print(stringConverter("zooneon"))
default:
print("something else : \(type(of: item))")
}
}
checkAnyType(of: 0) //zero as an Int
checkAnyType(of: 0.0) //zero as a Double
checkAnyType(of: 39) //an Integer value of 39
checkAnyType(of: 3.14) //a positive double value of 3.14
checkAnyType(of: "Hello") //a string value of "Hello"
checkAnyType(of: { (name: String) -> String in "Hello, \(name)" }) //Hello, zooneon