[swift] 옵셔널 타입, 언래핑, 옵셔널 바인딩, 캐스팅, 타입, any
옵셔널 타입
값을 반환할 때 뭔가... 오류가 있을법한 느낌이 드는데? 라고 생각 들면 optional 을 써서 반환하자.
사용 방법은 타입 뒤에 ? 을 붙이는 것이다. 이렇게. 변수 명 뒤에다 말고 자료형 뒤에..;
왜 옵셔널을 쓰는가? 값을 갖지 않는다는 nil 값을 가질 수 있기 때문이다
var index : Int?
결과가 뭘까? Int? 옵셔널 타입에 10이라는 값을 초기화 시켜놓고 Int("20") 으로 넣어봤다. 그럼?
옵셔널 이라는 타입으로 보호막이 씌어져있다.
그렇다면 index 변수에 Int("hello") 을 넣어보면?
optional 이 방어해주고 nil (null) 을 넣어줬다. optional ( Int? ) 을 안썼으면 오류가 났었겠지.
optional 이 방어를 해준다고 해서 천하무적은 아니다. 아래와 같이 당연히 Int에 String 을 썼을 때에는 무용지물이다.
옵셔널 타입 뜯어보기 (unwrapping) - 1 (무식한방법)
옵셔널 타입을 print 해보면 optional(10) 처럼 optional 이 감싸고 있는 것을 확인했다. 이걸 뜯어보자.
이렇게 강제로 옵셔널 타입의 변수에 값이 있으면 강제로 변수명 뒤에 ! 을 붙여 뜯을 수 있다.
하지만 값이 없는데 강제로 뜯어버리면...? print(index!)
방금 처럼 무식하게 뜯어버리지 말고 조금 더 안전하게 뜯어보자
index 가 nil 이 아닌지 확인을 한번 하는 if 문을 통해 값이 있는지 확인을 하자.
주의해야할게 index != nil 에서 != 을 붙여 쓰면 안된다
index! 이라고 먼저 해석하려고 하기 때문이다 ㄷㄷ 까다로운놈
옵셔널 타입 뜯어보기 (unwrapping) - 2 optional binding
두번 째 방법으로 임시 변수에 할당해서 뜯어보는 방법이다. if 문 뒤에 var 또는 let 으로 변수를 선언해서
옵셔널 값을 뜯어보고 값이 있으면 변수에 넣어서 사용하는 방법이다.
if let 변수 = 옵셔널 {
// 값이 있으면 언래핑 해서 변수에 값 넣고 이부분 실행, 값이 없다면 할게 없겠지
}
응용으로 한번에 여러 개의 옵셔널 변수를 언래핑 할 수 있다 한꺼번에.
myPet 과 yourPet 이 한 묶음으로 if 문에 들어왔으니. 하나라도 옵셔널 변수에 값이 들어있지 않다면 nil 로 가겠지?
nil
옵셔널 변수에 nil 을 할당하면 값이 없는 상태다. 상수나 변수가 값이 없는 상태가 존재할 수 있다면 옵셔널 변수로 선언해야 한다.
형 변환 (upcasting)
자식 클래스 -> 부모 클래스로 형변환 시키는 것. as 를 쓴다.
자식 -> 부모꺼의 객체로 변환 하는거니까 실패할 일이 없다. 부모 클래스의 메소드, 속성을 사용하기 위해서이다.
Shape type 이지만 Rectangle() 으로 초기화 시켰다
하지만 또 이걸 Shape 로 바꿨다.
그럼 Rectangle 내용을 쓸 수 있을까 없을까?
형 변환 (downcasting)
부모 -> 자식 으로 형변환(casting) 을 하는 것이다.
자식클래스의 메소드/속성을 사용하려고..
성공 자신이 있다면 as! 키워드를 사용.(변환이 실패되면 crash가 난다)
자신이 없다면 as? 키워드를 사용 한다. (변환이 실패되도 nil을 리턴한다. 최소한 crash 는 안난다.)
이렇게 Rectangle 에 있는 radious 변수를 사용하려면
rect 의 type은 Shape 로 선언했지만 저렇게 인스턴스를 Rectangle() 으로 선언해서
형변환 (rect as? Rectangle) 을 해서 접근한다.
여기서 부모는 Shape 이겠고. 자식은 Rectangle 이겠지?
타입 검사 (is/type(of: ))
값의 타입 검사.
인스턴스가 해당 클래스인가?
변수가 해당 자료형인가?
if rect is String {
}
if myObject is myClass {
}
또는 type(of: ~~) 으로 사용할 수도 있다.
꼭 비교하는 type 에는 .Type 을 명시해야한다.
Int.Type 뭐 이렇게. 그냥 Int 이라고 하면 안됨.
Any / AnyObject
Any : 함수 타입을 포함한 모든 타입의 인스턴스 가능
AnyObject : Class 타입의 인스턴스 가능
var anyArray : [Any] = [1, "이", 3.0, true]타입이 각자 제각각인데? 가능하다. Any 니까
그럼 AnyObject 는? Class 타입만 가능하다고 했다.
class A { }class B { }var anyObjectArray : [AnyObject] = [A(), B()]