본문 바로가기
Swift랑 친해지기/Swift 책보면서 정리해보기

옵셔널(Optional)

by 데브킹덕 2022. 2. 3.

🔥옵셔널🔥

스위프트가 잠재적 오류를 다루는 방법

 

옵셔널은 스위프트에서 도입된 새로운 개념으로서 언어 차원에서 프로그램의 안전성을 높이기 위해 사용하는 개념

옵셔널을 한문장으로 간략히 정의하자면 nil을 사용할 수 있는 타입과 없는 타입을 구분하고,

사용할 수 있는 타입을 가리켜 옵셔널 타입(Optional type)이라고 부른다고 할 수 있음 

 

nil

 값이 없음을  나타내는 특수한 값

정수형0과 문자열""과는 다름 순수하게 아무 값도 없다는 것을 의미함

이 때문에 nil은 종종 실제 값으로는 처리할 수 없는 , 무엇인가 문제가 발생했을 때 이를 의미하기 위해 사용함 

* objective-c에서는 빈 메모리 주소를 가리키는 값이 였음

 

예를 들어서 딕셔너리 변수명 뒤에 대괄호와 함께 키값을 주어야 하는데

오타로 잘못 쓰거나 삭제된 키를 사용하는 경우가 생길 수 있음.

근데 스위프트는 안전성을 최대한 높이고자 노력하는 언어여서

값을 처리하는 과정에 문제가 있어도 많은 부분에서 오류를 발생시키지 않음.

오류가 발생되지 않는 대신 문제가 있음을 사용자에게 알려줘야 되지 않겠음??

그래서 nil이라는 값을 반환하는거임

근데 모든 타입에서는 nil을 반환할 수 있는게 아니고

오로지 옵셔널 타입에서만 nil을 반환 할 수 있음 

 

오류가 발생할 수 있는 가능성이 아주 조금이라도 있으면 옵셔널 타입으로 정의해야 함

 

 

 Int(문자열)을 예로 들수 있겠음

문자열 "123"일때 -> 숫자로 변환 하면 

// Int (바꿀 문자열)
let num = Int("123")

- Int 객체의 생성자 옵션에 숫자로 변환할 문자열을 넣어주면 정수로 변환이 됨 

 

만약 문자열을 인자값으로 넣으면 어떻게 될까??

일반 문자열은 숫자로 변환할 수 없지만 오류로 반환하지 않음

왜 why ?? 오류가 발생하면 프로그램의 실행 흐름이 중단되고 앱의 동작이 멈추거나 아예 꺼져버릴 수도 있기 때문임

때문에 안전성을 위해서는 피해야 되서 오류를 발생시키지 않고 억지로 값을 반환하려고 함 

 

문자열을 숫자로 변환하려고 할때 오류가 나지 않고 nil을 반환하는 코드

보시다시피 nil을 반환하는 것을 볼 수 있음

 

때문에 Int(문자열)은 오류 가능성이 있기 때문에

 옵셔널 타입의 정수값을 반환하도록 설계되어 있는거임

 

옵셔널 타입

(Optional Type)

 

 반환하고자 하는 값을 옵셔널 객체로 다시 한번 감싼 형태

스위프트에서는 오류 발생할 가능성이 있기만 하면,

성공적으로 처리했더라도 옵셔널 타입으로 감싸서 반환함

 

옵셔널 타입은 별도로 존재하는 자료형이 아님

어떤 자료형을 사용하는지에 따라 대응하는 옵셔널 타입이 다름 

정수 타입을 옵셔널 타입으로 변경하면 Optional Int 타입이 되고,

문자열 타입을 옵셔널 타입으로 변경하면 Optional String이 됨

 

옵셔널 타입의 값 종류 두가지

1. nil이 아닌값

- 실제 실행 결과에서 오류가 발생하지 않았을 때 반환 

- 옵셔널 객체로 감싸진 결과값이 반환 

2. nil 값 

- 실제 실행 과정에서 오류가 발생 했을 때 

1. nil이 아닌값 예제

  - 문자열 "123"을 숫자로 변환한 값을 반환하고자 한다면 실제로 변환된 값 123을 직접 반환하는 것이 아니라 옵셔널 타입으로 값을

감싼 Optional(123)을 반환함

2. nil 값 예제

 - 정상적인 변환이 불가능한 상황이므로 Optional("Swift")가 아니라 nil값을 반환함 

 

결론 Optional(123) 과 nil은 모두 옵셔널 타입이다. 

 

처리가 성공적일 경우(nil이 아닌 값)

* 실제 값이 옵셔널 타입으로 둘러 쌓여 있는 것을 옵셔널 래핑(Optional Wrapping)

* 이렇게 해서 받은 값을 옵셔널 언래핑(Optional Unwrapping)이라고 불리는 특수한 처리 과정을 통해

옵셔널 타입을 해제하고 실제 값을 추출하여 사용해야 함

 

처리 결과가 실패일 경우(nil)

옵셔널 타입을 해제해서는 안됨

 

TMI)

그러면 일반 타입과 옵셔널 타입을 나누지 않고 무조건 모든 값에 옵셔널 타입으로 선언하고 사용하면 안됨??

-> 일반 자료형에 nil값을 허용하는 것과 다를바가 없음

또한 값을 사용할때마다 nil인지 아닌지를 체크하여 사용해야함

이렇게 되면 로직을 복잡하게 만들고 처리과정 또한 어려워짐 

 

*꼭 필요한 경우에만 제한적으로 옵셔널 타입을 적용하는 것이 좋음*