🔥 Any와 AnyObject를 위한 타입 캐스팅
Swift는 모든 타입의 값을 담을 수 있는 타입으로 작업하기 위한 두 가지 특별한 타입을 제공해요:
Any
는 함수 타입을 포함한 모든 타입의 인스턴스를 나타낼 수 있어요.AnyObject
는 모든 클래스 타입의 인스턴스를 나타낼 수 있지요.
Any
와 AnyObject
는 그것들이 제공하는 동작과 기능이 명시적으로 필요할 때만 사용하세요. 코드에서 작업할 것으로 예상되는 타입에 대해 구체적으로 명시하는 것이 항상 더 좋답니다.
다음은 함수 타입과 비클래스 타입을 포함한 다양한 타입의 혼합으로 작업하기 위해 Any
를 사용하는 예시예요. 이 예제는 Any
타입의 값을 저장할 수 있는 things
라는 배열을 생성해요:
var things: [Any] = [] things.append(0) // Int 값 추가 things.append(0.0) // Double 값 추가 things.append(42) // 또 다른 Int 값 추가 things.append(3.14159) // 또 다른 Double 값 추가 things.append("hello") // String 값 추가 things.append((3.0, 5.0)) // (Double, Double) 타입의 튜플 추가 things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman")) // Movie 인스턴스 추가 things.append({ (name: String) -> String in "Hello, \(name)" }) // String을 받아 String을 반환하는 클로저 추가
swift
things
배열은 두 개의 Int
값, 두 개의 Double
값, 하나의 String
값, (Double, Double)
타입의 튜플, "Ghostbusters" 영화, 그리고 String
값을 받아 다른 String
값을 반환하는 클로저 표현식을 포함하고 있어요.
Any
또는 AnyObject
타입으로만 알려진 상수나 변수의 특정 타입을 발견하기 위해, switch
문의 case
에서 is
또는 as
패턴을 사용할 수 있어요. 아래 예제는 things
배열의 항목을 반복하고 switch
문으로 각 항목의 타입을 쿼리합니다. switch
문의 여러 case
는 매치된 값을 지정된 타입의 상수에 바인딩하여 그 값을 출력할 수 있게 해줘요:
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
swift
이 예제는 things
배열의 각 항목을 순회하면서, switch
문을 사용해 각 항목의 타입을 확인해요. 각 case
는 특정 타입과 매치되는지 검사하고, 매치되는 경우 해당 값을 적절한 타입의 상수에 바인딩하지요. 그리고 바인딩된 값을 사용해 적절한 메시지를 출력합니다.
이처럼 Any
와 AnyObject
를 사용하면 다양한 타입을 하나의 컬렉션에 저장하고 다룰 수 있어요. 하지만 이는 타입 안전성을 희생시키는 것이기 때문에, 꼭 필요한 경우에만 사용해야 해요. 가능하면 항상 구체적인 타입을 사용하는 것이 좋답니다.
아래는 Any
타입의 값을 다룰 때 주의해야 할 점들을 정리한 도표예요:
이 도표는 Any
타입을 사용할 때 명시적인 타입 캐스팅이 필요하다는 것을 보여줘요. as
연산자를 사용해 구체적인 타입으로 캐스팅을 시도할 수 있는데, 이때 캐스팅이 성공하면 해당 타입의 값으로 사용할 수 있지만 실패하면 런타임 에러가 발생해요. 또한 is
연산자를 사용해 특정 타입인지 확인할 수 있어요. 특정 타입이라면 그 타입에 맞는 처리를 할 수 있지만, 그렇지 않다면 다른 타입에 대한 처리가 별도로 필요하지요.