반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

[1/2] Optional unwrapping 본문

오뚝이 개발자/swift

[1/2] Optional unwrapping

rriver2 2022. 5. 14. 19:30
반응형

 

옵셔널이 뭔지는 알고 있었는데, 정확하게 몰라서 그냥 가장 쉬운 방법인 !로 강제 추출해서 사용을 했었다. 

매번 하루 날 잡고 공부해야지... 해야지... 하다가 이제서야 각잡고 optional 공부를 했다.

 

optional을 공부하면서 든 생각은

optional 덕분에 swift는 다른 언어들 보다 좀 더 안전적이고 암묵적인 커뮤니케이션이 가능하게 된 것 같다는 생각이었다. 🧚🏻‍♀️👍🏻✨

 


 

 💡 optional 이란 ?  

 

swift에서 optional은 변수나 상수에 값이 있을수도, 혹은 없을수도 있다는 의미로 사용이 된다.

이때 주의할 점은 Int 형 일 때 0이나, String형 일 때 ""(빈 문자열이라는 의미)도 값이 들어가 있는 것이다. 

정말로 값이 없을 때만 nil이라고 한다. 

 

처음에는 optional이 왜 필요한 지에 대해서 몰랐었는데, 쓰다보니까 여러 오류들을 만나게 되고, 그 필요성이 점점 생겨나갔다.

 

사용되는 경우 )

내가 지금까지 optional을 사용한 경우에는 함수에 전달되는 전달인자 값이 잘못되었을 경우에 nil을 반환 하거나, 매개변수를 굳이 받지 않아도 될 때 nil을 사용하기도 했다. 

 


 

 💡 optional 사용법  

아래와 같이 데이터 타입 뒤에 ?를 붙여주면 된다 !

let name : String? = "River"
name = nil

 

 

String?을 String 변수에 넣을 수 없다.

 

왜 그럴까?

optional은 enum 타입인데, none 이거나 wrapped된 값으로 존재하게 된다. 

따라서 위에서 "must be unwrapped to a value of type String"이라는 오류가 뜬 것이다.

 

그래서 위 코드에서 name을 출력하게 되면 이렇게 name의 값인 "River"가 wrapped되어 print 된다. 

 


 

 💡 optional unwrapping  

음냠냠 위에서 optional에 대해 알아봤고, wrapped가 무엇인지 알아보았다.

그렇다면 이제 unwrapping을 알아볼 차례 !


  1) forced unwrapping 

optional 인 name 뒤에 !를 붙여이면 강제로 unwrapping을 시켜서 반환을 해준다.

let name : String? = "River"

// 이렇게 !를 붙여주면 강제로 unwrapping해서 String 타입으로 됨
let _name : String = name!

 

근데 이 방법은 ... 완전 Bad,, Bad 내가 100%,, 아니 200% 여기에는 nil 값이 들어가지 않을꺼야 ! 하지 않는 이상,

사용하지 않는 것이 좋다.

 

 

왜냐면,, 코드에서는 에러가 안 뜨는데 만약에 코드를 run한 후에,

이렇게 옵셔널 값이 nil 일 때는 런타임 에러가 발생하게 된다...!

 


  2) optional binding  

➯  if let을 이용해서 unwrapping을 할 수도 있다. 

아래 식은 " age가 nil이 아니라면 _age에 age 값을 넣겠다 " 라는 뜻이다.

(원래 _을 변수나 상수명에 쓰는 건 지양해야 하는데 unwrapping해서 썼다는 것을 나타내기 위해 표시해둔 거다..! )

var age : Int? = 22
if let _age : Int = age{
	// 이 블럭 내에서만 _age 사용 가능
    print("성공 ! \(_age)")
}else{
	// 이 블럭 내에서는 _age 사용 불가 
    print("실패 !")
}
// _age 사용 불가

 

 if let에서는 , (콤마)로 여러 optional 값을 한번에 추출 가능하다 .

let height : Int? = 160
let age : Int? = 22

if let _height : Int = height, let _age : Int = age{
    print("성공 ! \(_age), \(_height)")
}else{
	print("실패 !")
}

 

만약 이때, height나 age 둘 중에 하나라도 nil이라면, 실패가 프린트 되게 된다.

여기서는 ,가 && 연산자라고 생각하면 이해하기 쉽다 !

 

 

height가 nil 값인지 확인한 후에 age가 nil인지 확인하게 된다.

그래서 만약 height가 nil이라면 age는 확인도 안 한다고 한다 ~

let height : Int? = 160
let age : Int? = nil

if let _height : Int = height, let _age : Int = age{
    print("성공 ! \(_age), \(_height)")
}else{
    print("실패 !")
}

 

➯ if let으로 unwrapping 할 때 조건을 다는 것도 가능하다 ! 

height이 nil이 아니면서, _height 값이 100보다 커야지 성공이 프린트 된다.

이때, 위와 마찬가지로 왼쪽에서부터 확인하기 때문에 _height 값을 다음 조건식에서 사용할 수 있게 된다.

if let _height : Int = height, _height > 100{
	print("성공 ! \(_height)")
}else{
	print("실패 !")
}

 

이렇게 if let을 통해서 여러 조건이나, optional 값을 동시에 unwrapping 할 수 있다.

+ 뒤에서 guard let도 알아보겠슘 !


  3) implicitly unwrapping optional  

이거는 class에서 자주 사용된다는데 블로그에 포스팅할 만큼 사용되는 상황에 대해 정확하게 이해하지는 못했다. ( 링크 참고 )

 

하지만 사용법은 뭔지 안다.. ( 반쪽짜리 공부  ^^  ~ )

 

기존에는 unwrapping을 위해서 !를 쓰거나 if let을 사용했었더라면,

타입 뒤에 !를 붙임으로 implicitly unwrapping optional임을 표시해둔다.

var place: String? = "Home"

// 이전의 방식들
let forcedPlace: String = place! // ! 필요
if let bindingPlace : String = place {
    print("성공 \(bindingPlace)")
}

//implicitly unwrapping optional  
var place2: String! = place
let implicitplace: String = place2 // ! 안해도 unwrapping된 값이 들어감

이렇게 !를 붙인 타입은 일반 값처럼 사용할 수 있으나, 옵셔널이기 때문에 nil도 할당이 가능하다.

하지만 nil이 할당되어 있을 때 접근을 시도하면 런타임 오류가 발생한다.


  + ) Using the Nil-Coalescing Operator  

nil-coalescing operator을 이용해서 ??를 적으면 nil 값일 때 들어갈 기본 값을 작성해둘 수 있다.

var color: String? = nil
print(color ?? "Green")

-> Green이 출력됨

반응형

'오뚝이 개발자 > swift' 카테고리의 다른 글

removeLast() vs popLast()  (0) 2022.05.24
[2/2] optional chaining  (6) 2022.05.14
Closure에서의 Capture ( feat . reference type) [2/3]  (4) 2022.05.11
Closure 넌 누구냐 ! [1/3]  (0) 2022.05.11
Property(1/4) - > StoredProperty  (0) 2022.04.27
Comments