안녕하세요!
드디어 금요일이네요!!! 이번주도 좋은 한 주가 되셨길 바라면서~!
정말 자주 사용되는 Optional Binding에 대해 알아볼게요☺️
❓ Optional Binding
Optional Binding은 이전 글의 Forced Unwrapping처럼 옵셔널을 해제해 주는 Optional Unwrapping 방법 중 하나입니다
그리고 Forced Unwrapping과 반대로 가장 많이 사용되면서 안전한 방법이기도 합니다
Optional Binding에는 크게 if let과 guard let 방법이 있습니다 (while let도 있는데, 거의 사용하지 않아요)
간단히 살펴보면 optionalUserName이라는 Optional String Type을 해제해줄 때 이런 형태로 사용하게 됩니다
let optionalUserName: String? = "Yunie"
if let userName = optionalUserName { } else { }
guard let userName = optionalUserName else { return }
두 방식은 조금씩 달라보이지만 옵셔널을 해제해 주는 흐름이 동일합니다 (언뜻 보면 if-else문 같기도 하죠?)
1. optionalUserName이 값이 있는지 없는지(=nil) 확인합니다
2. 그리고 값이 있다면 새로 정의한 userName에 그 값을 넣어줍니다
3. 만약 nil이라면 else문으로 들어가게 됩니다
이제 if-let 방식부터 차근차근히 살펴볼게요!
❓if-let
if let 방식은 정말 if-else문과 다를게 거의 없습니다
그래서 사실 이해하시는데 어렵지 않으실 것 같아요
이전에 "안녕하세요! Yunie의 블로그입니다"를 출력하기위해 !를 사용해 강제로 옵셔널을 해제해 준 적 있죠
오늘은 안전하게 if let으로 한 번 옵셔널 상자를 열어줍시다

뭔지 모르셔도 괜찮습니다!
해당 코드들을 한 줄씩 살펴볼게요
1. 저는 if let 구문의 userName과 헷갈리지않게 optionalUserName이라는 이름으로 Optional String Type에 "Yunie"라는 값을 넣어줬습니다
var optionalUserName: String? = "Yunie"
2. 그리고 if let을 통해 optionalUserName에 값이 있는지 혹은 nil인지 확인합니다
if let userName = optionalUserName
3-1. 지금은 Yunie라는 값이 들어있으니까 옵셔널 상자에서 꺼낸 Yunie값이 userName에 담기게 됩니다
그리고 바로 뒤의 구문이 실행되어 이미지와 같은 결과를 보여주게 됩니다
{ print("안녕하세요! \(userName)의 블로그입니다") }
3-2. 그런데 만약 optionalUserName이 nil이라면?
2번의 과정에서 optionalUserName이 nil인 게 확인돼 바로 else 뒤의 구문이 실행됩니다
else { print("엥? nil인데요?") }

이처럼 if-let은 우리가 흔히 아는 그 if-else문처럼 생각하고 사용해 주시면 편합니다
값이 있을 때 = true, nil일 때 = false 이런 식으로요!
여기서 주의할 점은 if-let은 if-else처럼 if가 사용되기 때문에 옵셔널을 해제해 준 값을 if문 외부에서는 사용할 수 없다는 겁니다
만약 옵셔널을 해제한 값을 가진 userName을 외부에서 불러주게 되면 아래 이미지처럼 userName이라는 데이터는 찾을 수 없는데? 하고 에러가 뜨게 됩니다

저는 이 점을 간과해서 처음에 조금 헤매기도 했었답니다..🥲
그리고 덧붙여서 알려드리자면 optionalUserName의 옵셔널을 해제한 값이 userName에 담긴 것뿐이지 optionalUserName 자체가 Non-Optional Type이 되는 것은 아닙니다

또 저는 코드 예제에서 변수와 상수를 좀 더 구분하기 쉽게 두 데이터 이름을 다르게 해 준 것뿐이지
옵셔널을 해제한 값을 담을 상수와 옵셔널 타입의 변수/상수는 이름이 같아도 괜찮습니다!

만약 두 개 이상의 옵셔널을 해제하고 싶다면?
let으로 옵셔널을 해제한 값을 담을 상수를 연달아 정의해 주면서 해제해 줄 수 있습니다!
if let userName = userName, let petName = petName { } else { }
더불어 Swift 5.7에서 업데이트가 된 사항으로 if let 구문을 보다 짧게 사용할 수도 있습니다
지금까지는 if let 변수명 = 변수명 으로 사용했다면 옵셔널 타입의 변수/상수 하나만으로도 옵셔널을 해제해줄 수 있어요!
if let userName { } else { }
❓ guard let
guard let도 if-let, if else와 유사하지만 약간의 차이점을 가지고 있습니다
guard는 guard문의 조건을 만족하지 못했을 때, else문을 실행시키는데요
이때 return 또는 throw를 사용해줘야 합니다
그래서 if-let, if-else와 달리 함수(메서드) 내에서만 사용할 수 있습니다
만약 함수(메서드) return이나 throw를 넣어주지 않는다면?
아래와 같이 return이나 throw로 guard문을 끝내줘~ 하는 에러가 발생합니다

이제 아까의 예시로 사용된 if-let 구문을 guard문으로 바꿔볼게요!

뭔가... 비슷한데.. 싶다가도 조금 다르죠?
guard문도 마찬가지로 코드 한 줄씩 볼까요?
1. 이번에는 그냥 userName이라는 이름으로 Optional String Type에 Yunie라는 값을 넣어줬습니다
var userName: String? = "Yunie"
2. 그리고 guard let을 통해 userName에 값이 있는지 혹은 값이 없는지(= nil) 확인합니다
userName에 값이 있으면 새로 정의된 userName에 값이 대입돼요
guard let userName = userName
3-1. 만약 userName이 nil이었다면 바로 뒤의 else문이 실행돼 엥? nil인데요?라는 문자열이 반환될 거예요
else { return "엥? nil인데요?" }
3-2. 지금은 userName에 Yunie라는 값이 있기 때문에 그 아래의 구문이 실행돼 안녕하세요! Yunie의 블로그입니다가 반환됩니다
return "안녕하세요! \(userName)의 블로그입니다"
여기서 if-let과의 차이를 아시겠나요?
우리가 흔히 사용하는 if문과 달리 guard문은 else에 관한 구문을 먼저 작성해 줍니다
guard! 지킨다는 의미처럼 guard문은 조건을 만족하지 않으면 딱 컴파일러를 막고서 뒤로 보내지 않는 겁니다
그래서 조건이 만족됐을 때야 else { } 뒤의 코드들을 실행시킬 수 있습니다
어찌 보면 메서드 자체가 guard문의 if 처리문이기 때문에 guard에서 조건을 만족한 변수는 이후 코드에서 자유롭게 사용할 수도 있고요!
그리고 guard let 또한 한 번에 여러 개의 조건을 처리해 줄 수 있고 condition을 넣어서 확인해 줄 수도 있습니다
guard let userName = userName, let petName = petName, isUser == true else { return }
또, 이렇게 짧게도 사용해줄 수 있습니다!
guard let userName else { }
✏️ 오늘의 요약

마무리
이렇게 Optional Binding에 대한 정리가 끝났습니다!👏
정말 자주 사용되는 문법인만큼 꼼꼼히 알아가면 좋을 것 같습니다 :)
다음 글에선 또 다른 Optional Unwrapping 방법에 대해 알아볼게요
📚 참고
https://voiddani.tistory.com/15
https://babbab2.tistory.com/17
'Swift' 카테고리의 다른 글
| ❓Nil Coalescing (??) (0) | 2024.07.03 |
|---|---|
| ❓ Implicitly Unwrapped Optional (1) | 2024.07.01 |
| ❓ Forced Unwrapping (0) | 2024.06.26 |
| ❓ Optional (0) | 2024.06.24 |
| ❓ Type Inference / Type Annotation (0) | 2024.06.21 |