안녕하세요 소들입니다 💀 (헬쓱)
퇴근 후 포스팅은 피곤하네여..
요즘 회사 일은 Objective-C로 개발하고
포스팅 및 개인 프로젝트는 Swift로 하니까
혼돈의 카오스
옵젝씨 코드에 세미콜론 빼먹어서 에러뜨고
스위프트 코드에 세미콜론 붙어 있고..
쨌든
이번 포스팅의 내용은
Swift로 iOS를 개발하려면 정말 정말 정말
매우 많이 사용하게 되고
중요한
Optional Binding
에 관한 것입니다 짞짞짝
자 고고씽~~~!!!
모든 스위프트 포스팅은 쓰기 쉬운 음 체로 감니다!!!
1. Optional Binding
먼저 Optional Binding은
Optional을 Unwrapping 하는 방법 중 하나임
앞서 살펴본 Optional Unwrapping의 특징은
다음과 같음
옵셔널 타입의 값을 사용할 땐
옵셔널을 해제해서 사용해야 하고
주의할 점은 nil이 지정된 경우엔 절대 해제하면 안 됨
Optional Unwrapping 방법 중엔
강제 추출(Forced Unwrapping) 방법이 있지만
이는 nil이 들어 있어도 강제로 해제해버리는 특성 때문에
진짜 얘 값 100프로 있다고 확신할 수 있는 경우를 제외하곤
웬만해선 사용하면 안 된다 했음
위 내용이 이해가 안 간다면
보고오셈
그럼 어떤 방법을 사용하냐?
바로 오늘 배울 것임
옵셔널 바인딩(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 구문에서 사용 불가) |
-끝-
피드백 환영 🌝
'iOS > Swift' 카테고리의 다른 글
Swift) Optional 부수기 (4) Optional Unwrapping - IUO (옵셔널 묵시적 추출) (5) | 2020.08.03 |
---|---|
Swift) COW (Copy-on-Write) (8) | 2020.07.31 |
Swift) Optional 부수기 (2) Optional Unwrapping - 강제 추출(Forced Unwrapping ) (6) | 2020.07.14 |
Swift) Optional 부수기 (1) Optional 정의 , nil , Non-Optional Type vs Optional Type (18) | 2020.07.12 |
Swift) 타입 추론(Type Inference) vs 타입 어노테이션(Type Annotation) (6) | 2020.07.09 |