기어가더라도 제대로

[Swift - 기초] Optional - 100 days of swiftUI 본문

Swift - 기초

[Swift - 기초] Optional - 100 days of swiftUI

Damagucci-juice 2022. 10. 4. 09:00

Optional

This thing might have a value or might not
값이 있을 수도 있고 없을 수도 있다.
  • 이런 개념이 생겨난 이유
    • 코드의 예측성을 더하기 위해서
    • 이 코드가 안전하고 예상한대로 잘 동작할 것이라는 예측
    • 데이터가 없는 데이터를 이용하지 못하도록 미리 조치

  • 값이 없는 키를 Dictionary 에 요청하면 Optional(nil) 이 나온다. 
  • Dictionary 의 value 타입을 String? 으로 지정하는 것이 더 좋다. 
  • optional 이라는 개념은 안에 값이 있을 수도 있고 없을 수도 있는 박스와 비슷하다. 

값이 없을 때를 대비하는 안전장치 - unwrapping

  • 값이 없을 때를 대비해서 조건문을 선언하는 if 키워드와 상수를 선언하는 let 키워드를 합치면
  • if let  이라는 옵셔널을 unwrapping 하는 방식이 생김

  • 이 코드에는 3가지 뜻이 담겨 있다. 
    1. dictionary 로 부터 optional 값을 읽는다.
    2. optional 내부에 값이 있다면 벗겨낸다. 그 값을 marioOpposite 에 넣는다. 
    3. 조건이 성공하면(optional 값을 벗겨낼 수 있으면) 조건문의 body 를 실행한다. 

nil 의 진짜 뜻

  • Int
    • 숫자 값이 반드시 존재함을 나타냄
    • 0 일수도 있고, 1백만일 수도 있음
  • Int?
    • 숫자 값이 있을 수도 있고 없을 수도 있음
    • nil 이라면 그땐 숫자가 없음, 아예 없음
      • 0 도 숫자임
      • 그냥 값자체가 공허하게 없는 것임
  • String
    • 문자열이 반드시 존재함을 나타냄
    • "hello" 일수도 있고 빈 문자열인 "" 일수도 있지만 값이 반드시 있음
  • String? 
    • 문자열이 있을수도 있고 없을 수도 있음
    • 문자열이 있다면 String 이고 없다면 nil
      • nil 은 빈문자열을 뜻하는 "" 이 아니다.
      • 그냥 값이 없는 것이다.
  • Array<Int>
    • 배열에 숫자가 있을 수도 있고 빈 배열일 수 있다.
    • 그치만 그건 빈 배열이지 nil 이 아니다.
  • Array<Int>?
    • 이 값이 nil 이라면 빈 배열이라는 뜻이 아니라 그냥 값 자체가 없다는 뜻이다. 

  • 이 코드를 실행해보면 오류를 낸다. 
  • 비 옵셔널 정수를 요구하는 파라메터에 옵셔널 정수를 넣을 수 없다. 

Shadowing

  • 이 코드는 오류를 낼까?
  • 문법적으로 전혀 문제가 없다. 
  • = 뒤에 number 는 외부의 옵셔널 값인 number 를 뜻하고 
  • = 앞에 number 는 조건문의 바디 안에서만 사용할 number 이다. 
  • 조건문 바깥에선 옵셔널 number 가 인식된다. 
  • 이를 shadowing(그림자) 라는 용어로 부른다. 
  • 주로 옵셔널 unwrapping 을 할 때 사용한다. 

guard 를 이용한 optional unwrapping

  • if let 이랑 비슷
  • 옵셔널 값이 없으면 그 자리에서 값을 반환하거나 해당 함수를 종료(ealry return)
  • Scope 안에서만 사용 가능
  • if let 은 옵셔널 값이 있어야 바디를 실행하는데, guard let 은 옵셔널 값이 없어야 바디를 실행
  • 값이 있나 없나를 검사하고 있으면 그 뒤의 코드를 실행하게 하고 없다면 else {} 안의 조기 종료 코드를 실행함
  • 값이 있으면 그 scope 안에선 unwrapping 된 값을 사용할 수 있음

  • 옵셔널 값을 사용하지 않고도 guard 문을 사용할 수 있다. 확인하는 용도
guard someArray.isEmpty else { return }

coalescing(합치기) 로 optional unwrapping

  • if let, guard let 에 이은 3번째 방법
  • 옵셔널 값이 nil 일 때 기본값을 설정할 수 있다.

  • 위에 new 는 타입이 String?
  • 아래 new 는 타입이 String
  • 이것을 가능하게 해주는 게 coalescing(합치기)
  • 옵셔널 값을 unwrapping 을 해주고 nil 일 경우에 기본값을 주어서 타입을 유지 시켜줌
    • 여기선 기본값 "N/A"

다수의 옵셔널을 다뤄보기 - optional chaining

  • 옵셔널 안에 옵셔널 값이 있을 때 사용하는 방법
  • 옵셔널 값안에 nil 이 있다면 아무 행동도 하지 않는다. 
  • 필요한 만큼 길게 쓸 수 있으며 중간에 nil 이 나오면 거기서 nil을 배출한다. 

함수가 실패하면 옵셔널로 대처하기 

  • 에러 가능성이 있는 코드에서 try 키워드로 시도 해볼 수 있음
  • 의도적으로 실패 가능성이 있는 함수의 경우 try? 를 사용해서 오류 가능성을 내포할 수 있음
    • 함수가 제대로 실행되면 결과값을 가진 옵셔널을 반환하고
    • 함수가 에러를 발생시키면 nil 을 반환한다.

  • 에러가 발생했는지 아닌지만 확인 가능
  • 주로 다음과 같은 상황에서 자주 쓰임
    1. guard let 과 nil?로 현재 함수가 값을 반환하는지 확인
    2. coalescing 에서 실패시 기본 값을 제공하도록 시도
    3. 반환 값이 없는 에러를 낼 가능성이 있는 함수를 호출 할 때, 성공과 실패가 중요하지 않을 때
      1. 로그 파일 작성, 분석 결과 서버로 전송 등
Comments