Swift 문법 - 옵셔널 바인딩(if let, guard let)과 옵셔널 체이닝, nil 병합 연산자

eelijus·2022년 12월 10일
0

Swift Syntax

목록 보기
6/11

💡옵셔널 바인딩, 옵셔널 추출, nil 병합 연산자

옵셔널 바인딩

  • if let (if var) : 옵셔널에 값이 있는지 없는지 확인하고, 값이 있으면 옵셔널이 아닌 형태로 바꿔줄게! & nil인지 값이 있는지 경우에 따라 결과를 다르게 해줄게!

    func printName(_name: String) {
      print(_name)
    }
    var myName: String? = nil
    //myName에 값이 있으면 name에 myName의 값을 할당하고 조건을 실행해!
    if let name = myName {
      printName(_name: name)
    } else {
      print("you are anonymous")
    }

    myName에 값이 있을때만 name에 값이 바인딩됨.




Unwrapping guard let

guard 문

  • 주어진 조건문이 거짓일 때 코드블럭을 실행시킨다.
  • if 문과는 달리 else 가 필수적이다.
func guardNil(string: String?) {
   // 인자로 들어오는 string은 nil이 아니어야해! 그렇지 않으면? 리턴시켜버려
   guard string != nil else { return }
   // 인자로 nil값이 들어왔으면 이미 guard 문에서 return됐을테니, 안심하고 추출해도 괜찮다.
   print(string!, “second parameter”, seperator: “”)
}

guard 문은 특성상 메서드에서만 쓰이며, guard 구문의 조건을 만족하지 못하면 else 문으로 빠져서 함수의 실행을 종료시킬 때 사용.

이 조건 만족 못하면 내 함수에서 나가!

  • 가드를 사용해 언래핑한 옵셔널은 가느다 끝난 후에도 머물러 있기 때문에 함수 내 가드문 밖에서도 언래핑된 문자열을 인쇄할 수 있다.
func unwrappingString(_string: String?) {
    guard let unwrappedString = string else {
        print(“this string is nil!)
        return 
    }

print(“string : \(string)!)

}


옵셔널 체이닝

하위 프로퍼티에 옵셔널 값이 있는지 연속적으로 확인하면서, 중간에 하나라도 nil이 발견되면 nil을 반환해주는 형식. 옵셔널의 내부의 내부의 내부로 옵셔널이 연결되어 있을 때 유용하게 활용할 수 있다. 매번 nil 확인을 하지 않고 최종적으로 원하는 값의 존재 유무를 확인 할 수 있음.

import Foundation

class Residence {
    var roomNumber = 0
}

class Person {
    //residence 라는 변수가 Residence 클래스를 옵셔널로 상속받음.
    //나중에 Person 타입의 인스턴스가 만들어지면 residence 변수의 초기값은 nil이 된다.
    var residence: Residence?
}


/*
sujilee는 Person 클래스에서 선언한 residence를 프로퍼티로 갖는다.
residence는 Residence 클래스를 옵셔널 타입으로 상속받고 있기 때문에 residence에는 값이 있을 수도, 없을 수도 있다.
옵셔널 타입은 별도로 초기화하지 않으면 nil값으로 초기화 되는건 기억하지?
*/

//인스턴스 sujilee 를 Person 타입으로 생성
//sujilee.residence의 값은 현재 nil이다.
let sujilee = Person()

if let roomNumberOfSujilee = sujilee.residence?.roomNumber {
    print("sujilee's room number is \(roomNumberOfSujilee)")
} else {
    print("Unable to retrieve sujilee's room number")
}

//OUTPUT : Unabale to retrieve sujilee's room number
  • 카뎃의 맥북 유무와 분야가 궁금하다면?
import Foundation

class Person {
    var name: String
    var laptop: Laptop?
    
    init(name: String) {
        self.name = name
    }
}

class Laptop {
    var owner: Person?
    var M1chip: String?
}

//옵셔널 체이닝이 실행된 후 결과값이 nil일 수 있으므로 결과 타입도 옵셔널이다. ???
let sujilee: Person? = Person(name: "sujilee")
let macbook: Laptop? = Laptop()


//옵셔널 체이닝을 사용하지 않을 경우
func showLMacbookChip(owner: Person?) {
    if let owner: Person = owner {
        if let macbook = owner.laptop {
            if let m1 = macbook.M1chip {
                print("\(owner.name)의 맥북은 \(m1)칩이다")
            } else {
                print("\(owner.name)의 맥북은 인텔칩이다")
            }
        } else {
            print("\(owner.name)은 맥북이 없다.")
        }
    }
}

showLMacbookChip(owner: sujilee)
//OUTPUT : sujilee는 맥북이 없다.

//옵셔널 체이닝을 사용할 경우
func showMacbookChipWithOptionalChaning(owner: Person?) {
    if let owner = owner {
        if let m1 = owner.laptop?.M1chip {
            print("\(owner.name)의 맥북은 \(m1)이다.")
        } else {
            print("\(owner.name)의 맥북은 인텔임.")
        }
    }
}

showMacbookChipWithOptionalChaning(owner: sujilee)
//OUTPUT : sujilee의 맥북은 인텔임

print(sujilee)
//OUTPUT : Optinal(Person)

print(sujilee?.laptop?.M1chip)
//OUTPUT : nil

sujilee?.laptop = macbook
print(sujilee?.laptop)
//OUTPUT : Optional(Laptop)

sujilee?.laptop?.M1chip
print(sujilee?.laptop?.M1chip)
//OUTPUT : nil

sujilee?.laptop?.M1chip = "intel"
print(sujilee?.laptop?.M1chip)
//OUTPUT : Optional("intel")


nil 병합 연산자

?? : 중위 여산자

//형태
Optional ?? Value

옵셔널 값이 nil일 경우, 우측의 값을 반환한다.

import Foundation

class Person {
    var name: String
    var laptop: Laptop?
    
    init(name: String) {
        self.name = name
    }
}

class Laptop {
    var owner: Person?
    var M1chip: String?
}

//옵셔널 체이닝이 실행된 후 결과값이 nil일 수 있으므로 결과 타입도 옵셔널이다. ???
let sujilee: Person? = Person(name: "sujilee")
let macbook: Laptop? = Laptop()

var possessionOfM1: String

//이러면 sujilee.laptop이 지금 nil이라 sujilee.laptop.M1chip도 nil인거임
sujilee?.laptop?.M1chip = "true"
print(sujilee?.laptop?.M1chip)
//OUTPUT : nil


sujilee?.laptop = macbook
sujilee?.laptop?.M1chip = "true"
possessionOfM1 = sujilee?.laptop?.M1chip ?? "false"
print(possessionOfM1)
//OUTPUT : true

sujilee?.laptop?.M1chip = nil
possessionOfM1 = sujilee?.laptop?.M1chip ?? "false"
print(possessionOfM1)
//OUTPUT : false




참고 :

https://yagom.github.io/swift_basic/contents/16_optional_chaining/

https://seons-dev.tistory.com/132

profile
sujileelea

0개의 댓글