Optional 옵셔널!(feat.swift)

3867 단어 swiftoptionaloptional

Optional이란 무엇인가!

오늘 포스팅 주제로 삼은 Optional은 내가 처음 Swift를 하면서 "정말정말정말" 이해하기 어려웠던 개념 두가지중 하나였다.
하나는 오늘 포스팅할 Optional이고, 나머지 하나는 Closure다.

아마, 내 나이대와 비슷하고 적당한 전자공학과에서 학부수준의 교육을 경험하면 입학부터 졸업할때 까지 배우는게 C/C++일텐데, 이것과는 느낌이 사뭇 다르다.
즉 익숙하지 않다는 얘기다.

무엇을 말하고싶은가?

왜 익숙하지 않은지에 대해 말하고싶다.
우리는 C/C++뿐 아니라 대부분의 프로그래밍언어에서 없는 값 에 대해서 처리할때 곤란함을 느낀다.
왜냐하면 어떠한 특정 변수를 선언하고, 그 변수에 값을 넣거나, 넣지 않게될 때가 있다.

// in C++
int x = 10;

이런식으로 선언하고 값을쓰는데 결국에 이러한 초기화의 행위가 곁들여진 이후에 변수에대한 값의 상태는 항상 "존재한다" 라는 것이 된다.

이후 상태로 봤을때는 "값이 얼마인가?" 에 초점이 맞춰지는데
그 전에 우리는 "값이 존재하는가?" 에대한 물음을 먼저 생각해 볼필요가있다.

이러한 부분에서 존재의 의미를 따지는게 Optional이라고 생각한다.
엄청 말을 장황하고 길게 썼지만, 논지는 하나다.
"값이 존재해?"

Optional

선 요약이다.

  • Non Optional타입은 항상 값을 가져야한다.
  • Optional타입은 값을 가지지 않을수 있다.
  • Optional타입의 선언은 기존의 타입 Annotation뒤에 ?만 붙힌다.
let str : String = "Swift" //상수선언
let optionalStr: String? = nil//Optional String선언

let a: Int? = nil//Optional Int선언

이런식으로 만들어진 Optional을 변수, 상수에 할당했을때의 타입은 어떤지 알아보자.

let b = a
print(tyoe(of: b))

이런식으로 사용할수 있고, b는 Optional타입을 가지게 된다.

Optional은 그럼 어떻게 쓰는가?

아마 Optional을 선언하고 그냥 그대로 쓰게되면

let a : Int? = 10
print(a)


위의 그림을 보게될것이다.
큰 그림을 봤을때, 느낄수 있는것은 Optional이라는 껍질이 10이라는 Int값을 감싸고있다는 느낌이 들것이다.
실제로 Optional이 Int나 자료형을 감싸고 있는형태로 Optional이 사용이 되고 값으로서 Optional을 활용하기 위해서는 우선 저 껍질을 벗겨야한다.

껍질을 제거해주는 방법은 몇가지가 있지만, 그중에 오늘은 두가지를 보려한다.

  • Forced Unwrapping
  • Binding

단순하게 생각하면, 강제로 없애는것과 유한 방법으로 없애는것이라고 생각하면 편할것 같다.

차근차근 알아보자

Forced Unwrapping

Unwrapping하고픈 사용할 변수의 뒤에 !을 붙히자

!을 뒤에 붙히면 Optional껍질 내부에있는것을 그냥 강제로 추출해오는 방식이다.
코드로서 사용하면 다음과 같다.

let a : Int? = 10
print(a!)

굉장히 Simple하고 Powerfull해 보인다!
근데 알겠지만 Forced한 방식이 있다고한것은 대체로 이 방식이 그다지 옳은 방법이 아니라는 얘기가된다.

왜그런지 먼저알아보자.
Optional의 값을 끌어오는것까진 좋다
하지만 Forced Unwrapping의 문제점은 바로 꺼낼 대상의 값이 존재하지 않는 경우이다.
프로그램이 동작하면서 크래시가 날수있는 요인중 하나다.
그래서 실제 서비스하는 앱에서 사용했다간.. 큰일이 날수 있는 것이라는 뜻이다.

만약 그럼에도 불구하고 이러한 기법을 사용해서 Unwrapping을 해야 한다면 최소한의 안전 장치는 하고가자.
안전 장치는 다음과 같다.

let num : Int? = nil
if num != nil {
	print(num!)
}

이런식으로 먼저 nil 즉 존재하는지 안하는지부터 확인을해서 크래시의 이유를 없애면 충분히 사용가능하다.

그래서 결론은 다음과 같다.

  • Optional안의 값을 사용하기 위해서는 Unwrapping을 해야한다.
  • 이러한것을 해결해줄수 있는 기법중 한개가 Forced Unwrapping이다.

Binding

이제부터 직관적이고 안전한 옵셔널 바인딩에 대해 알아보자.
코드를 먼저 보겠는데,

var num : Int? = nil
if num != nil {
	print(num!)
}else {
	print("Empty")
}

이런식으로 사용하는것이 위에서 배웠던 Forced Unwrapping방식인데
Binding에서는

if let n = num {
	print(n)
}else {
	print("empty")
}

이런식으로 문제를 해결할수 있는데, 이러한 방식을 Optional Binding이라고 한다.
Binding에는 크게 3가지가 있다.

  • if let or var 저장장소 = Unwrapping대상 {
  • while let or var 저장장소 = Unwrapping대상 {
  • guard let or var 저장장소 else { End }

위의 기법들을 이용해 Binding을하고 저러한 문장들을 전부 바인딩 이라고 얘기를한다.

위의 바인딩 키워드를 통해 사용이 가능한데, 특이한 점이 있다면 guard 부분이다.
다른 키워드의 Binding요소들은 어떠한 특정조건의 분기점에서 안된다면, 다음 분기점을 가는 절차지향의 느낌이 난다.
하지만 guard는 Binding실패시 바로 함수를 종료시키는 특징이 있다.

예를 하나만 들고 오늘의 정리를 끝내야겠다.

var str: String? = "str"
guard let str = str else {
    fatalError()
}

guard는 이런식으로 사용하게된다.

정리 끝!

좋은 웹페이지 즐겨찾기