swift 기본문법 - 타입 캐스팅(type casting)

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
인프런, 야곰의 스위프트 기본문법 강좌를 듣고 정리하였습니다.


타입 캐스팅(type casting)

스위프트의 타입캐스팅은 인스턴스의 타입을 확인하는 용도로 사용한다. 뿐만 아니라 클래스의 인스턴스를, 부모 혹은 자식클래스의 타입으로 사용할 수 있는 지 확인하는 용도로 사용한다.

is, as를 사용한다.

let someInt: Int = 100
let someDouble: Double = Double(someInt)

이는 스위프트에서 타입캐스팅이 아니다. 그저 Double타입의 인스턴스를 더 생성해준 것일 뿐이다.

스위프트의 타입캐스팅은 클래스의 인스턴스에서 사용할 있다.

class Person {
  var name: String = ""
  func breath() {
    print("숨을 쉽니다")
  }
}

class Student: Person {
  var school: String = ""
  func goToSchool() {
    print("등교를 합니다")
  }
}

class UniversityStudent: Student {
  var major: String = ""
  func goToMT() {
    print("멤버쉽 트레이닝을 갑니다!")
  }
}

var zehye: Person = Person()
var hana: Student = Student()
var jason: UniversityStudent = UniversityStudent()

타입확인 - is

var result: Bool

result = zehye is Person  // true
result = zehye is Student  // false
result = zehye is UniversityStudent  // false

result = hana is Person   // true
result = hana is Student   // true
result = hana is UniversityStudent  // false

result = jason is Person    // true
result = jason is Student   // true
result = jason is UniversityStudent   // true

업 캐스팅 - as

as를 사용하여 부모클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 타입정보를 전환해준다. Any 혹은 AnyObject로도 타입 정보를 변환할 수 있다. > 암시적으로 처리되므로 생략해도 무방하다

var mike: Person = UniversityStudent() as Person
var jenny: Student = Student()
var jina: Any = Person() // as Any 생략가능

var jina: UniversityStudent = Person() as UniversityStudent  // 컴파일 오류
  • Person타입이라고 하더라도 UniversityStudent의 인스턴스가 들어올 수 있다 » 왜냐면 대학생은 사람이기 때문

다운 캐스팅 - as? 또는 as!

자식 클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 인스턴스의 타입정보를 전환해준다.(사람으로 지정했는데 학생일수도 있느냐?)

  • as? 조건부 다운캐스팅
  • as! 강제 다운캐스팅

조건부 다운캐스팅 as?

var optionalCasted: Student?

optionalCasted = mike as? UniversityStudent
optionalCasted = jenny as? UniversityStudent  // nil
optionalCasted = jina as? UniversityStudent   // nil
optionalCasted = jina as? Student  // nil
  • mike: Person 타입으로 되어잇어도 UniversityStudent로 캐스팅될 수 있다.
  • 나머지: 사람이거나 학생이었기 때문에 캐스팅이 될 수 없다.  » nil이 반환

조건부 다운캐스팅을 하게 되면 결과값이 옵셔널값이 나온다.

강제 다운캐스팅 as!

var forcedCasted: Student

optionalCasted = mike as! UniversityStudent
optionalCasted = jenny as! UniversityStudent  // 런타임 오류
optionalCasted = jina as! UniversityStudent   // 런타임 오류
optionalCasted = jina as! Student  // 런타임 오류
  • mike: 원래 대학생 타입이었기 때문에 문제없이 진행된다.
  • 나머지: 대학생이 될 수 없기 때문에 오류가 발생한다.

강제 다운캐스팅은 위험요소가 있지만 반환타입이 옵셔널이 아닌 일반 타입이기 떄문에 편하게 사용가능하다.

주로 함수로 전달되는 경우 확인해볼 수 있다.

func doSonethingWithSwitch(someone: Person) {
  switch someone {
  case is UniversityStudent:
    (someone as! UniversityStudent).goToMT()
  }
  case is Student {
    (someone as! Student).goToSchool()
  }
  case is Person {
    (someone as! Person).breath()
  }
}

switch구문을 할때는 확인만 할 뿐이지 실제 캐스팅을 하고싶다면 직접 실행을 해야한다.

그렇기 때문에 if let구문을 사용한다.  » 옵셔널 결과값을 받아와 옵셔널 추출을 한다.

func doSonethingWithSwitch(someone: Person) {
  if let universityStudent = someone as? UniversityStudent {
    universityStudent.goToMT()
  } else if let student = someone as? Student {
    student.goToSchool()
  } else if let person = someone as? Person {
    person.breath()
  }
}