12/12 TIL 옵셔널

handaewon·2023년 12월 12일
1

옵셔널

☑️ 옵셔널(Optional)

  • 값이 없을 수 있는 상황에서 옵셔널(Optional)을 사용합니다.
  • 옵셔널은 물음표 ? 로 나타냅니다. (타입 어노테이션)
  • 옵셔널은 두 가지 가능성을 나타냅니다.
    • 값이 있고 옵셔널로 래핑(wrapping)해놓은 값을 언래핑(unwrapping)하여 해당 값에 액세스할 수 있다.
    • 값이 전혀 없다.
  • 옵셔널 타입끼리의 연산은 불가능
var serverResponseCode: Int? = 404

var myPetName: Optional<String> = "고양이"

func pay(with card: String?) {
    
}
var num1: Int? = 4
var num2: Int? = 2

num1 + num2
//에러 발생!

let optionalString1: String? = "Hello, "
let optionalString2: String? = "World!"

코드
Binary operator '+' cannot be applied to two 'Int?' operands
Binary operator '+' cannot be applied to two 'String?' operands

☑️nil
옵셔널 변수에 특수한 값 nil 로 지정하여 값이 없는 상태를 나타낼 수 있습니다:

var serverResponseCode: Int? = 404
serverResponseCode = nil

var surveyAnswer: String?

☑️ 옵셔널 바인딩
옵셔널 바인딩은 옵셔널 값이 빈값인지 존재하는지 검사한 후, 존재하는 경우 그 값을 다른 변수에 대입시켜 바인딩하는 것을 의미합니다.
이렇게 빈 값을 체크하고 옵셔널 값을 언래핑 해주는 것은 강제로 언래핑하는 것보다 훨씬 안전합니다.
if let / if var, guard let / guard var을 써서 옵셔널 값을 추출해 새로운 변수에 바인딩합니다.
if let vs guard let 차이점
if let은 if문의 코드 구현부 내에서만 상수 사용이 가능합니다.(지역 변수)
guard let 은 guard문을 통과한 상수를 guard문 밖에서 사용이 가능합니다.(전역변수)

let roommateNumbers: Int? = nil
if let roommates = roommateNumbers {
    print (roommates)
}
// 출력값 없음

let ticketCounts: Int? = 3
if let ticket = ticketCounts {
    print (ticket)
}

//  옵셔널 바인딩 할 변수가 여러 개인 경우
let boyName : String?
let girlName : String?

boyName = "태형"
girlName = "소미"

// , 콤마로 나열합니다
if let boy = boyName,
    let girl = girlName {
    print(boy, girl)
}

let x : Int? = 10
let y : Int? = nil

func opbinding() {
    guard let x = x else { return }
    print(x)
    
    guard let y = y else { return }
    print(y)
    }

opbinding()

☑️ 옵셔널 강제 언래핑
강제 언래핑(Force unwrapping)은 !를 써서 강제로 옵셔널 추출합니다.
(변수 앞에 !를 붙이는 것은 not의 의미 - 헷갈리지 말것!)
강제 언래핑을 잘못 사용할 경우 프로그램이 비정상적으로 종료될 수도 있으므로 반드시 nil이 아닌 것이 확실한 상황에서 사용해야합니다.(최대한 안쓰는게 좋습니다)

☑️ 옵셔널 체이닝

  • 옵셔널을 연쇄적으로 사용하는 것을 옵셔널 체이닝이라고 합니다.
  • . 을 통해 내부 프로퍼티나 메서드에 연속적으로 접근할 때 옵셔널 값이 있으면 옵셔널 체이닝으로 접근할 수 있습니다.
let number = Int("42")!
print(number)

let adress: String? = nil
print(adress!)

// 4)
var optNumber: Int? = 3
let number = optNumber ?? 5

optNumber = nil
let number2 = optNumber ?? 5
print(number)

print(heartPath)

//5)옵셔널 체이닝
struct Person {
    var name: String
    var address: Address
}

struct Address {
    var city: String
    var street: String
    var detail: String
}

let dan: Person? = Person(name: "Dan", address: Address(city: "서울", street: "서초대로", detail: "105"))
print(dan.address.city)
dan?.address.city
profile
iOS Developer

1개의 댓글

comment-user-thumbnail
2023년 12월 13일

깔끔한 정리 좋습니다 😝

답글 달기