타입 캐스팅을 수행할 때 일반적으로 상속 관계에 있는 클래스끼리만 캐스팅이 가능하지만,
Any와 AnyObject 타입을 사용할 경우, 상속 관계에 있지 않아도 타입 캐스팅을 할 수 있다.
함수타입을 포함하여 모든 타입의 인스턴스를 나타낼 수 있습니다.
사실 스위프트 안전한 언어여서 → 타입에 굉장히 민감한 부분이 있다.
BUT. Any를 활용하면 모든 타입을 저장할 수 있다.
Value 타입(구조체, 열거형), Reference 타입(클래스, 클로저)이건 상관 없이 모두 사용 가능하다!
var nums: [Int] = []
nums.append(1)
nums.append(1.0) // Cannot convert value of type 'Double' to expected argument type 'Int'
nums.append("sodeul") // Cannot convert value of type 'String' to expected argument type 'Int'
nums.append(false) // Cannot convert value of type 'Bool' to expected argument type 'Int
var things: [Any] = []
things.append(1)
things.append(1.0)
things.append("sodeul")
things.append(false)
things.append(Human.init()))
things.append({ print("I am Sodeul!") })
AnyObject는 모든 클래스 타입의 인스턴스를 나타낼 수 있습니다.
Any보단 한단계 더 까다로운 AnyObject → 클래스 타입만 저장
아래와 같이 클래스 인스턴스를 제외하고 모두가 에러난다!
var things: [AnyObject] = []
things.append(1) // Argument type 'Int' expected to be an instance of a class
things.append(1.0) // Argument type 'Double' expected to be an instance of a class
things.append("sodeul") // Argument type 'String' expected to be an instance of a class
things.append(false) // Argument type 'Bool' expected to be an instance of a class
things.append(Teacher.init()))
things.append({ print("I am Sodeul!") }) // Argument type '()->()' expected to be an instance of a clas
switch 문을 활용해서, 해당 타입일 경우(캐스팅에 성공한 경우) case문이 실행될 수 있게 할 수 있다.
for thing in things {
switch thing {
case _ as Int:
print("Int Type!")
case _ as Double:
print("Double Type!")
case _ as String:
print("String Type!")
case _ as Human:
print("Human Type")
case _ as () -> ():
print("Closure Type")
default:
print("something else")
}
}
Any & AnyObject가 모든 타입을 저장할 수 있어 편해보이지만 상속관계가 없기 때문에 관련된 타입의 메소드 등을 사용할 수 없다.