-
[SWIFT] Optional #3iOS/SWIFT 2022. 8. 29. 19:46728x90반응형
첫번째로 시작했던 앱개발 프로젝트가 끝난 뒤 여행을 다녀왔다 덕분에 마음의 평화는 조금 생겼다만 다시 게을러질 뻔한 나 자신을 발견하고 말았다. 항상 여행도 좋고 다양한 사람들을 만나는건 좋지만 본인이 해야할 일을 절대로 잊어선 안된다는 것을 깨달아 버렸다.
옵셔널(Optional)
자 오늘은 optional에 대해서 끄적일 계획이다.
일단 Optional에 대한 정의는 이렇다.
"값이 있을수도 있고 없을 수도 있는 것"
옵셔널을 직역하면 '선택적인'이라는 단어가 나오는데 스위프트는 프로그램에 안정성을 중요시 하기 때문에 오류대신 nil을 반환하도록 유도하여 옵셔널 타입을 만들게 된것이다.
일단 여기서 짚고 넘어가야할 것이 있는데 nil이라는 값은 타 언어의 NULL 처럼 빈값이다. 정확하게 말하면 '빈값'일 뿐이지 '값이 없다'가 아니다 그럼으로 진짜로 값이 비어있을 경우에는 nil이 아닌 에러가 나오게 된다. 그것을 방지 하기 위해 우리는 옵셔널이라는 것을 쓰는 것이다.
옵셔널의 선언 방식은 다음과 같다.
var val:Int? print(val) //Optional(3) print(val!) //3
우리가 아는 변수 프로퍼티와 선언은 같으나 타입 뒤에 ?문자를 추가하면 된다.
그리고 보통 변수선언과 동시에 초기화를 해줘야겠지만 옵셔널이기 때문에 빈값으로 선언해도 에러는 생기지 않고 nil값이 저장되게 된다. 어찌보면 옵셔널 타입의 특징이라고도 볼수 있다. 그리고 옵셔널로 선언된 변수라도 엄연히 그냥 변수의 타입과는 다르기 때문에 Int로 선언된 변수에 Int? 타입을 저장을 할수는 없다.
위에 코드를 보면 이상한 것이 보인다.
val 변수를 바로 출력하면 옵셔널이라는것에 감싸져 나오는 것을 확인 할 수 있다. 여기서 우리는 래핑이라는 개념을 알아야하는데 옵셔널타입은 옵셔널로 감싸져 있는 상태인데 그것을 '래핑'이라고 한다. 래핑 된 상태에서는 연산을 지원하지 않는다. 따라서 감싸져 있는것 을 해제해줄 '언래핑'을 해줘야한다. 위와 같이 데이터뒤에 !를 붙여서 강제로 언래핑하는 방법도 있고(묵시적 해제) 다른 방법이 있는데 우린 그 다른 방법을 많이 사용하게 된다. 한번 살펴보자
옵셔널 바인딩 (Optional Binding)
옵셔널 바인딩이라는 것은 강제언래핑이 아닌 조건문으로 언래핑을 진행해주는 것인데, 이것은 명시적 해제에 해당 된다. 사용방법은 다음과 같다.
if let unwrapVal = val{ print(unwrapVal) //3 }
이것은 일반적인 방법의 옵셔널 바인딩인데 이렇게 다른 특정 프로퍼티를 선언하여 그 안의 값이 있을 경우 그값을 언래핑하여 저장하는 방식이다. 저번 글에서 배웠듯이 굳이 조건문의 조건을 달지 않아도 true/false로 나오기 때문에 true일 때 언래핑을 해주는 것이다. 그리고 한번 벗겨서 저장을 했기 때문에 묵시적 해제를 하지 않아도 사용이 가능하게 된다.
let numVal = val ?? 30 //변수 안에 값이 nil일 경우 값을 넣어줌 print(numVal)
이런식으로 조건문을 사용하지 않고도 언래핑이 가능하다.
다른 방법도 있다.
var fristVal:Int? = 11 var secondVal:Int? = nil func unWrap(_ param: Int?){ guard let unwrapVal = param else{ print("참이 아님") return } print(unwrapVal) } unWrap(fristVal) //11 unWrap(secondVal) //참이 아님
guard let 방법인데 바로 전에 알아봤던 if let과는 비슷하면서도 매우 다르다. 결론 부터 말하면 guard let은 true일 때는 코드를 계속 실행하지만 false일 때는 구문안에 있는 코드를 실행한다. 또 그 구문에서는 무조건 제어문 전환 명령어를 써줘야한다 ex) continue, break, return 등
if let과 guard let의 차이점
if let guard let 사용 범위 지역변수 전역변수 else문 생략 가능 생략 불가 활용 성공과 실패의 분기로 특정 요구사항일 경우 if let에 경우 위의 표와 같이 언래핑 성공과 실패 사례로 두가지의 조건에서 구문을 실행할 수 있으며, 지역변수임으로 그 조건안에서만 변수가 사용가능함에 비해 guard let은 특정한 상황에서만 동작 시키고 싶은 경우 if let에 비해 훨씬 코드가 간결하게 작성 할 수 있는 장점이 존재한다.
옵셔널 체이닝 (Optional Chaining)
이번 개념은 옵셔널 체이닝에 관한 내용이다. 옵셔널 체이닝은 말그대로 옵셔널을 사슬 처럼 연달아서 사용하는 것을 말하는데 특정 옵셔널에 접근하기위해 옵셔널을 사용하는 것이다. 공부를 위한 공부같은 느낌..? 다음 예제를 살펴보자
struct Information { var grade : Int var major : String } struct Student { var name : String var info : Information init(_ name : String, _ grade : Int, _ major : String) { self.name = name info = Information(grade : grade, major : major) } } var quarang : Student? = Student("콰랑", 1, "스위프트학과") //변수를 옵셔널로 선언한 후 구조체 저장 //quarang = nil if let myname = quarang?.name, let myinfo = quarang?.info{ print("나는 \(myinfo.grade)학년 \(myinfo.major) \(myname)입니다.") //나는 1학년 스위프트학과 콰랑입니다. }else{ print("존재하지 않는 학생입니다.") }
위와 같이 Infomation 구조체를 사용 하는 Student 구조체이다. Student구조체를 사용하기 위해서는 변수 프로퍼티를 옵셔널의 형태로 선언을 하여 사용해야한다. 또한 접근할 시에도 변수 뒤에 ?를 붙여 옵셔널이라는 것을 알려줘야한다. 그래서 그 변수가 nil인지 아닌지 확인하여 결과를 도출할 수가 있다.
옵셔널 체이닝은 우리가 특정 내부값이나 메서드의 연속적으로 접근 할때( ex: quarang?.name) '?' 즉 옵셔널 값이 하나라도 들어가 있으면 그것이 옵셔널 체이닝이다. 물론 하나라도 들어있지 않으면 옵셔널 체이닝이 아니다.
그리고 하나더 위의 예제에서 quarang 변수는 Student의 옵셔널 값의 객체변수 인데 만약 name값이 옵셔널인 name?로 선언 되있어도 quarang?.name?이라고 하지는 않는데(에러) 옵셔널의 마지막값은 옵셔널이던 아니던 ?를 붙이지 않는다고 한다.
'iOS > SWIFT' 카테고리의 다른 글
[SWIFT] 연산프로퍼티 #6 (0) 2022.09.29 [SWIFT] 클래스/구조체 #5 (0) 2022.09.13 [SWIFT] Enum #4 (0) 2022.09.06 [SWIFT] 조건문과 반복문#2 (0) 2022.06.30 [SWIFT] 저장 프로퍼티#1 (0) 2022.06.17