본문 바로가기

iOS/Swift

Swift) Optional 부수기 (3) Optional Unwrapping - 옵셔널 바인딩(if let vs guard let)

안녕하세요 소들입니다 💀 (헬쓱)

퇴근 후 포스팅은 피곤하네여..

 

요즘 회사 일은 Objective-C로 개발하고

포스팅 및 개인 프로젝트는 Swift로 하니까

혼돈의 카오스

옵젝씨 코드에 세미콜론 빼먹어서 에러뜨고

스위프트 코드에 세미콜론 붙어 있고..

 

쨌든

이번 포스팅의 내용은

 

Swift로 iOS를 개발하려면 정말 정말 정말

매우 많이 사용하게 되고

중요한

 

Optional Binding

 

에 관한 것입니다 짞짞짝

자 고고씽~~~!!!

 

모든 스위프트 포스팅은 쓰기 쉬운 음 체로 감니다!!!

 

 

 

 

 

1. Optional Binding

 

먼저 Optional Binding은

Optional을 Unwrapping 하는 방법 중 하나임

 

앞서 살펴본 Optional Unwrapping의 특징은

다음과 같음

 

옵셔널 타입의 값을 사용할 땐 

옵셔널을 해제해서 사용해야 하고

주의할 점은 nil이 지정된 경우엔 절대 해제하면 안 됨

 

Optional Unwrapping 방법 중엔

강제 추출(Forced Unwrapping) 방법이 있지만

이는 nil이 들어 있어도 강제로 해제해버리는 특성 때문에

진짜 얘 값 100프로 있다고 확신할 수 있는 경우를 제외하곤

웬만해선 사용하면 안 된다 했음

 

위 내용이 이해가 안 간다면

소들이의 Optional Unwrapping 1편

보고오셈

 

그럼 어떤 방법을 사용하냐?

바로 오늘 배울 것임

 

옵셔널 바인딩(Optional Binding)

 

이 옵셔널 바인딩을 사용하면

안전하게 Optional의 값을 Unwrapping 할 수 있음

 

어떻게?

다음 세 가지 Syntax를 통해!

 

 

엥 이게 모임 할  수 있음

근데 대충 위 방식들의 공통점은

 

1. 옵셔널 표현식을 먼저 평가한다.

2. 값이 있는 경우(nil이 아닌 경우) 정의된 상수(name)에 옵셔널이 해제된 값을 저장하고 true를 반환한다.

3. 값이 없는 경우(nil)인 경우 false를 반환한다

4. 타입 추론이 되므로 Type Annotation은 대부분 생략한다

 

이런 방식인데 이해 안 갈 수 있음

이제 예제를 통해 하나씩 알아 보면 이해 갈 거임

참고로 while을 이용한 방법은 거의 사용되지 않기 때문에

while은 제외하고 알아볼 거임

 

 

 

 

 

2.  if let 

 

첫 번째 방법은 if let을 이용한 방법임

먼저 Syntax는 위에서 봤으니

예제를 통해 보겠음

 

 

위처럼 옵셔널 타입의 optionalNum이라는 상수가 있음

 

 if let을 이용하여 옵셔널 바인딩을을 하면

다음과 같이 사용 가능함

 

 

 

사용은 이런 식으로 함

매커니즘 설명 할거지만 일단 이해하기 쉬우라고 주석 달아놓음

 

먼저 위 구문의 결과 값은

 

 

4라는 옵셔널이 해제된 값이 나옴

 

만약 num에 nil이 지정 됐다면?

 

 

 

결과 값은

 

 

 

오호..

매우 똑똑하군?

 

 

.

.

자 메커니즘은 다음과 같음

 

 

 ①  표현식이 nil인지 아닌지 판별하자  

 

 

 ②  표현식이 nil이 아닌 경우 

 

 

optionalNum의 값이 nil이 아닌 경우,

optionalNum을 Unwrapping 한 값을 nonOptionalNum에 대입함

 

이제 우린 Unwrapping된 값인 nonOptionalNum이란 상수를 사용하면 됨

 

근데 여기서 주의할 점이 몇 가지 있음

 

 

❗️ 첫 번째 주의할 점

 

nonOptionalNum 이라고 if let을 통해 선언된 상수의 scope는 if 구문임

 

무슨말이냐?

 

 

 

이런 식으로 if 문 밖에서는 nonOptionalNum이라는 상수에 접근할 수 없음

 

 

❗️ 두 번째 주의할 점

 

nonOptionalNum은 optionalNum을 Unwrapping 한 값을 대입한 것 뿐

optionalNum의 값은 여전히 Optional Type이다

 

예제 보면 이해 단박에 감

 

 

위 구문의 결과 값은

 

 

 

 

optionalNum을 Unwrapping 한 값이 nonOptionalNum일 뿐,

optionalNum은 여전히 Optional Type의 값임

 

그 외엔 딱히 주의할 점 없음

 

 

 

 

  ③  표현식이 nil인 경우 

 

 

nil인 경우엔 if 구문을 거치지 않고

else 구문으로 빠짐

당연하게도 nonOptionalNum 이란 상수는 사용할 수 없음 (위에서 설명했음)

 

 

if let은 이정도 이해 했으면 더 설명할 것은 없고 

이제 guard let 문으로 가겠음

 

 

 

🥕 Tip 1

 

Optional Binding을 사용하다 보면

바인딩 될 Non Optional Type의 이름을 짓는 것이 굉장히 귀찮고 힘들고 난해함

그럴 땐 그냥 Optional Type의 이름을 그대로 똑같이 써도 됨

 

 

이런 식으루 말이지

근데 위에서 주의할 듯이

Scope는 꼭 알아두고 주의하길

 

(만약 두 개의 변수가 서로 다른 Scope에서 같은 이름으로 선언된 경우,

실행 시점에서 가까운 곳에 선언된 변수로 선택됩니당~~~~)

 

 

 

🥕 Tip 2

 

 

이런 식으로 한번에 여러 개의 옵셔널 타입을 바인딩 할 수도 있음

이때는 name, age 모두 nil이 아니여야 if구문이 true가 됨

 

또한

 

 

이런 식으로 condition을 넣어줄 수 있음

마찬가지로 

name, age가 nil이 아니여야 하고, age의 값이 5보다 커야 true가 됨

 

 

 

 

 

 

3. guard let 

 

guard let도 if let과 비슷하지만

다른 점이 있음

 

먼저 guard라는 것은 지키다라는 뜻이잖음?

 

guard문은 특성상 함수(메서드)에서만 쓰이며,

guard 구문의 조건을 만족하지 못하면

else문으로 빠져서 함수의 실행을 종료 시킬 때 사용함(return을 떄림)

 

한 마디로

 

너 이 조건 만족 못하면

내 함수에서 나가!

 

이렇게 가드하는 것임

조건을 만족하지 못하면 내쳐버리는 것이 바로 guard문의 특성임

따라서 guard 구문은 else 와 pair로 다님

왜냐? 조건 못지키면 else에서 return 때려버려야 하걸랑

 

예제로 ㄱㄱ

 

 

 

아까와 같이 이런 변수가 있을 때

guard 문은 다음과 같이 사용함

 

 

 

 

if let을 통해 대충 어떤 건지 감이 왔을텐께

매커니즘부터 설명 하겠음

 

 

 

 ①  표현식이 nil인지 아닌지 판별하자 

 

 

 

 

  ②  표현식이 nil이 아닌 경우 

 

 

guard 문에선 표현식이 nil이 아닐 경우 else 문으로 빠지지 않고

원래 guard문을 실행시키던 scope로 돌아옴

 

 

자 그럼 이제 다음과 같이

NonOptionalNum이라는 Optional이 해제된 값을

guard 구문 밖에서 사용할 수 있음

 

 

 

 

 

결과값도 Unwrapping된 값으로 잘 나옴

 

 

if문과 뭐가 다른지 이해 감?

옵셔널 바인딩 된 상수 nonOptionalNum의 Scope가 다름

 

if문은 if문 안에서만 사용 가능 했다면,

guard문은 guard문 밖에서 사용 가능함

 

 

 

❗️주의할 점

 

옵셔널 바인딩된 nonOptionalNum의 Scope는 guard 구문 밖임

따라서 else문에서는 nonOptionalNum을 사용할 수 없음

 

요렇겡

 

 

 

 

 ③  표현식이 nil인 경우 

 

앞서 누누히 말해왔듯이

표현식이 nil인 경우엔

 

이렇게 else 구문으로 빠져서

return을 때리거나 실행을 종료하는 것이

일반적임

 

참고로 이때는 당연히

nonOptionalNum의 값을 사용할 수 없음

 

 

 

🥕 Tip 1.

 

guard let 구문도 if let과 마찬가지로 

Optional Binding 될 NonOptional Type의 상수 이름을 

Optional Type의 이름과 같게 사용할 수 있을까?

 

 

결론부터 말하면

 

경우에 따라 다름

 

무슨 말이냐면,

if 구문 같은 경우는 언제든 옵셔널 타입과 논 옵셔널 타입의 이름을 같게 선언해줘도 됐음

그러나 guard문은 함수(메서드)의 매개변수로 들어온 표현식에 한해서만 가능함

 

예제로 ㄱㄱ

 

 

⭕️ 가능한 경우

함수(메서드)로 넘어온 파라미터 값(임시 상수 혹은 변수)를 바인딩 할 경우

 

 

이런 경우엔 바인딩 되는 표현식의 이름을 같게 해줘도 가능함

 

 

 

❌ 불가능한 경우

함수(메서드) 내에서 선언한 상수 혹은 변수를 바인딩 할 경우

 

 

 

이 경우엔 이름을 같게 해줄 수 없음

 

찾아보면 scope의 문제라는데,,,,

근데 파라미터 임시 상수의 scope가 함수 전역으로 알고 있고,

위의 num도 저렇게 선언하면 함수 전역이 scope일텐데

왜 되고 안되는지는 확실히 모르겠음..

 

쨌든 경우에 따라 다르단 것만 알아두고

혹시 위의 문제점에 대해 명쾌한 답을 알면 댓글로 좀 알려주셈 ㅜㅜ

 

 

 

🥕Tip 2.

 

if let과 마찬가지로 다음과 같이 사용이 가능함

 

 

옵셔널 바인딩을 하나의 gurad문에서 연속으로 할 수도 있고,

condition을 넣을 수 있음

 

 

 

 

 

 

 

4. if let vs guard let

 

그럼 언제 if let을 쓰고 언제 guard let을 쓸까?

위에서 설명하면서 다 말했음

꼼꼼히 읽었다면 알 것임

 

 

🍏

if let

- 단순히 옵셔널 처리 값에 대한 피드백만 주고 싶을 때

- 너 값 있으면 이렇게 처리하고 nil 이면 저렇게 처리해!

 

🍎

guard let

- 옵셔널 처리 값이 nil인 경우 무조건 함수의 실행을 종료 시킬 때

- 너 값 없니? 그럼 내 함수에서 나가

 

 

 

 

 

 

5. 정리

 

  if let guard let
선언
표현식이 nil일 경우 if 조건문이 false가 됨 else문이 실행됨
표현식이 nil이 아닐 경우 if 조건문이 true가 됨 guard 구문 종료
(함수 이어서 실행)
사용 용도 표현식이 nil인지 평가하여 
간단한 피드백을 줄 때
표현식이 nil인지 평가하여
nil일 경우 함수 실행을 종료시킬 때
바인딩된 상수의 scope
(선언 구문에서 name이 바인딩된 상수)
if 구문 안에서만 사용 가능
(else 구문 및 밖에서 사용 불가)
guard 구문 밖에서만 사용 가능
(else 구문에서 사용 불가)

 

 

 

 

 

 

-끝-

피드백 환영 🌝

 



Calendar
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
최근 댓글
Visits
Today
Yesterday