Swift문법 - (24)옵셔널타입의 응용

Youth·2022년 10월 17일
0

swift문법공부

목록 보기
24/27
post-thumbnail

옵셔널 체이닝(Chaining)

  • 옵셔널타입에 대해 접근연산자를 사용하는 방법
class Dog {
    var name: String?
    var weight: Int
    
    init(name: String, weight: Int) {
        self.name = name
        self.weight = weight
    }
    
    func sit() {
        print("\(self.name)가 앉았습니다.")
    }
    
    func layDown() {
        print("누웠습니다.")
    }
}

class Human {
    var dog: Dog?
}

만약에 인스턴스가 옵셔널타입이라면?

var choco: Dog? = Dog(name: "초코", weight: 15)

에러가 발생하고 choco뒤에 ?를 붙여야한다고 제안해준다

choco?.name
choco?.sit()

→ choco가 옵셔널 가능성이 있는경우 메서드를 “.”으로 접근할때 ?를 붙여야한다


Human인스턴스가 옵셔널로 선언이 되어있다면?

var human2: Human? = Human()

choco는 Dog?타입이기 때문에 dog의 타입과 일치해서 대입이 가능하다

human2?.dog = choco
human2?.dog?.name

human2도 옵셔널 dog도 옵셔널 name도 옵셔널이라서 전부다 ?를 붙여야할거같지만

→ 마지막건 옵셔널이어도 ?를 붙이지 않아도 괜찮다

💡 옵셔널 체이닝 (옵셔널 타입에 대해, 접근연산자 호출하는 방법)
  • 옵셔널체이닝의 결과는 항상 옵셔널이다.
  • 옵셔널체이닝에 값 중에서 하나라도 nil을 리턴한다면, 이어지는 표현식을 평가하지 않고 nil을 리턴

옵셔널 체이닝의 실제사용(Unwrapping)

  1. 앞의 옵셔널타입에 값이 있다는 것이 확실한 경우
print(human2!.dog!.name) -> 옵셔널 타입으로 결과값이 나오기때문에 언래핑
print(human2!.dog!.name!) -> 강제언래핑한 경우
print(human2!.dog!.weight) -> weight는 옵셔널이 아니라 그냥 사용 가능
  1. if let 바인딩
if let name = human2?.dog?.name {   
    print(name)
}
  1. Nil-Coalescing 연산자
var defaultName = human2?.dog?.name ?? "멍탱구리"
print(defaultName)

옵셔널 체이닝 - 함수 관련 표기법

class Cat {
		// 함수가 있을수도 있고 없을수도 있다
    var myMaster: (() -> Person?)?
    init(aFunction: @escaping () -> Person?) {
        self.myMaster = aFunction
    }
}

class Person {
    var name: String?
}

// return이 있을수도 있고 없을수도 있다
func meowmeow() -> Person? {
    let person = Person()
    person.name = "Jobs"
    return person
}

인스턴스를 하나 만들어보면

var cat: Cat? = Cat(aFunction: meowmeow)

그리고 cat인스턴스안에 name이라는 키워드에 접근하려면

→ cat에 있는 mymaster이라는 함수에 접근해서 인스턴스를 반환한거에 name에 접근

  1. cat자체가 옵셔널일 수 있음
  2. myMaster이라는 함수자체가 옵셔널일 수 있음
  3. myMaster이라는 함수의 결과값이 옵셔널일 수 있음
  4. name이 옵셔널일 수 있음(마지막이라서 ?생략 가능)
var name = cat?.myMaster?()?.name

→ 소괄호 앞의 ?는 함수의 옵셔널 여부 뒤의 ?는 결과값의 옵셔널 여부

옵셔널 체이닝 - 딕셔너리 관련 표기법

class Library1 {
    var books: [String: Person]?
}

var person1 = Person()
person1.name = "Jobs"

var person2 = Person()
person2.name = "Musk"
var library = Library1()
library.books = ["Apple": person1, "Tesla": person2]
  1. 딕셔너리 자체가 옵셔널일 수 있음
  2. 딕셔너리 자체의 값이 없을 수 있음(value) → 모든 딕셔너리 값은 옵셔널임
library.books?["Apple"]?.name
library.books?["Tesla"]?.name

옵셔널 체이닝에서 함수의 실행

  • 옵셔널 타입에 접근해서 사용하는 함수는 앞의 타입을 벗기지 않아도 사용가능 함.
    (함수자체가 옵셔널 타입은 아니기 때문에 함수를 벗겨서 사용할 필요없음)
  • 함수가 리턴형이 없는 경우
    (1) 타입에 값이 있으면 함수실행
    (2) 타입에 값이 없으면 nil
  • 함수가 리턴형이 있는 경우
    (1) 타입에 값이 있으면 옵셔널 리턴 타입으로 반환 (원래 리턴형이 옵셔널이 아니더라도)
    (2) 타입에 값이 없으면 nil로 반환
var bori: Dog? = Dog(name: "보리", weight: 20)

// ⭐️ 앞의 타입이 옵셔널이라고 해서 메서드가 실행이 안되는 것은 아님
bori?.layDown() 
bori?.sit()    
bori = nil
// 타입의 값이 nil이면, 함수가 실행이 되지 않고 nil을 반
bori?.layDown()  
profile
AppleDeveloperAcademy@POSTECH 1기 수료, SOPT 32기 iOS파트 수료

0개의 댓글