0. Intro) 범용 타입

타입 캐스팅을 수행할 때 일반적으로 상속 관계에 있는 클래스끼리만 캐스팅이 가능하지만,

Any와 AnyObject 타입을 사용할 경우, 상속 관계에 있지 않아도 타입 캐스팅을 할 수 있다.

1. Any

함수타입을 포함하여 모든 타입의 인스턴스를 나타낼 수 있습니다.

사실 스위프트 안전한 언어여서 → 타입에 굉장히 민감한 부분이 있다.

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!") })

2. AnyObject

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

3. Any & AnyObject의 타입 캐스팅

i) as를 이용한 패턴 매칭(switch)

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")
    }
}

ii) as? as!를 이용한 다운캐스팅(Downcasting)

Any & AnyObject가 모든 타입을 저장할 수 있어 편해보이지만 상속관계가 없기 때문에 관련된 타입의 메소드 등을 사용할 수 없다.