// Dog, Cat, Bird의 parent type은 Animal이다.
func walk(dog: Dog) {
  print(”Walking \(dog.name)”)
}
 
func cleanLitterBox(cat: Cat) {
  print(”Cleaning the \(cat.boxSize) litter box’”)
}
func cleanCage(bird: Bird) {
  print(”Removing the \(bird.featherColor) feathers at the 
    bottom of the cage’”)
let pet = getClientPet() // return Animal
 
if let dog = pet as? Dog {
  walk(dog: dog)
} else if let cat = pet as? Cat {
  cleanLitterBox(cat: cat)
} else if let bird = pet as? Bird {
  cleanCage(bird: bird)
}
강제로 특정 type으로 downcast한다.
만약 downcast가 불가능하면, 에러를 반환한다.
특정 type임을 확신할 수 있을 경우에만 사용한다.
let alansDog = fetchPet(for: “Alan”) // Animal type
let alansDog = fetchPet(for: “Alan”) as! Dog // Dog type
UIKit API는 보통 매우 포괄적인 type을 반환한다. ex) UIViewController
FirstViewController에 있는 버튼을 터치하면 SecondViewController가 보여진다고 가정하자.
이 경우, 개발자는 SecondViewController가 반환됨을 확신할 수 있으므로 as!를 사용할 수 있다.
class SecondViewController: UIViewController {
  var names: [String]?
}
 
// 새로운 view controller가 보여질 때마다 실행되는 함수
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  // destination을 SecondViewController로 강제로 downcast
  let secondVC = segue.destination as! SecondViewController
  secondVC.names = [”Peter”, “Jamie”, “Tricia”]
}
”
Any: 모든 type의 instance
AnyObject: 모든 class의 instance
// 다양한 type의 instance가 들어있는 collection을 생성할 수 있다.
var items: [Any] = [5, “Bill”, 6.7, true]
// as? 를 통해 구체적인 type을 추출한다.
if let firstItem = items[0] as? Int {
  print(firstItem + 4) // 9
}