- Total
꿈꾸는리버리
[1/2] Optional unwrapping 본문
옵셔널이 뭔지는 알고 있었는데, 정확하게 몰라서 그냥 가장 쉬운 방법인 !로 강제 추출해서 사용을 했었다.
매번 하루 날 잡고 공부해야지... 해야지... 하다가 이제서야 각잡고 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 |