Swift 문법(기본편) - 옵셔널

천성우·2023년 5월 10일
0

iOS_swift_문법

목록 보기
2/3

옵셔널


Swift는 안전한 코딩을 할 수 있게 해주는 언어라고 알려져 있습니다. 그리고 안전성의 중요한 요소 중 하나가Optional(옵셔널)이라는 개념입니다. 옵셔널은 타입 캐스팅이나 nil value 체크 등에 있어 중요한 역할을 하고 있습니다.

Optional
”이 변수에는 값이 들어갈 수도 있고, 아닐 수도 있어”

옵셔널의 간략한 의미를 보자면 위의 말과 같다고 볼 수 있습니다.

즉, nil을 표현하기 위한 수단으로 ?, Optional<타입>을 (둘 다 사용가능 !)사용하는 것 입니다.

let wooseongcheon: String?
let jiyoungheo: Optional<String>

// 위처럼 변수의 타입 뒤에 ?를 붙여주면 해당 변수는 옵셔널이 됩니다. 

1주차에서 다룬 것 처럼 swift는 기본적으로 상수나 변수에 nil 값을 지정할 수 없지만 **?**를 사용하여 해당하는 변수를 옵셔널로 변경해 준다면 nil을 할당할 수 있습니다.

let SO: String? = nil // 오류 X
let PT: String = nil // 'nil' cannot initialize specified type 'String'

옵셔널 추출


옵셔널 추출은 말 그대로 옵셔널인 값을 옵셔널이 아닌 값으로 추출해주는 것을 뜻 합니다.

swift는 옵셔널 타입과 논 옵셔널 타입을 철저히 구분하여 처리하기 때문에 만약 논 옵셔널 타입이 필요할 때는

꼭 옵셔널 추출 과정이 필요합니다

// 옵셔널 타입, 논 옵셔널 타입?? 
let test1: String = nil    // -> Non-Optional Type
let test2: String? = nil   // -> Optional Type

Non-Optional Type vs Optional Type

let text1: String = "iOS 32기"
let text2: String? = "천성우"

print(type(of: text1))
print(type(of: text2))

위 코드르 보면 알 수 있듯 Non-Optional과 Optional은 근본적으로 Type(자료형)이 다릅니다.

그리하여 만약 Optional Type 형식의 변수를 사용하려면 Optional이라는 포장지에서 값을 꺼내오는 과정을 거쳐야하는데 이를 Optional Wrapping이라고 합니다

Optional Wrapping

Optional Type은 기본적으로 wrap되어 있는 상태입니다. 즉 Optional Type의 변수는 값이 있는 것인지, nil인 건지 모르는 상태라는 것 입니다. 그렇기 때문에 만약 변수에 값이 있더라도 변수가 출력되지 않습니다

let text2: String? = "천성우"
print(text2)
// 출력 결과 : Optional("천성우") 

위와 같은 상황일 때 text2는 nil일 수도 있기 때문에, 결과값이 Optional(”천성우”)라고 출력되는 것 입니다

Forced Unwrapping(강제 추출)

위와 같은 예시에서 출력 결과가 원하는 것 처럼 나오지 않을 경우 간단하게 사용할 수 있는 방법이 Forced Unwrapping입니다. 사용 형태는 !, 즉 느낌표로 우리가 Optional로 선언했지만 무조건 변수가 있는 상황이 보장될 경우 우리가 원하는 결과값을 출력할 수 있습니다

❗ 옵셔널 타입에 값이 있다고 확신하는 경우사용할 것을 권장 ❗

let text2: String? = "천성우"
print(text2!)
// 출력 결과 : 천성우

Optional Binding

Optional 타입으로 선언된 변수에 값이 있는지 없는지를 확인해주는 기능으로 Optional Binding을 사용하면 느낌표 없이 Optional 타입의 변수 값을 출력할 수 있어서 강체 추출보다 좀 더 안정적인 형태로 결과값을 출력할 수 있습니다

Forced UnWrapping: !를 사용하여 강제로 추출
Optional Binding: if let, guard let 을 사용하여 옵셔널의 값 존재 유무를 검사한 뒤, 존재한다면 그 값을 다른 변수에 대입해주는 방식으로 추출

if let vs guard let

let text1: String? = nil

if let safeword = text1 {
    print(safeword)
}else {
    print("nil")
}

func text() -> Void {
    guard let safeword2 = text1 else { return }
    print(safeword2)
}
text()
  1. if let

    text1을 가지고 예시 코드를 돌렸다

    만약 text1이 nil이 아니면 safeword 값을 바인딩 후 값을 출력하고

    아니라면 nil을 출력한다

  2. guard let

    만약 text1의 값이 nil이 아니라면 safeword를 출력 수행하며 아니라면 return 하는 형태

Optional Chaining

Optional Chaining은 옵셔널일 수 있는 인스턴스 내부의 프로퍼티, 메소드, 서브스크립트를 매번 nil 체크를 하지 않고 최종적으로 원하는 값, 혹은 nil인지 판단하는 방법입니다. 여러개를 함께 연결 할 수 있고, 연결된 어떤 링크라도 하나가 nil이라면 nil 값이 나옵니다

간단하게 cheon?.seong?.woo 이런 형태로 프로퍼티나 메소드에 연속적으로 접근할 때 옵셔널 값이 하나라도 껴 있으면 Optional Chaining이라고 볼 수 있음

// 구조체 예시

struct Contacts {
	var email: String
}

struct Person {
	var name: String
	var contacts: Contacts

	init(name: String, email: String){
		self.name = name
		contact = Contacts(email: email)
	}
}

var cheon: Person? = Person(name: "seongwoo", email: "cjs1399@gmail.com")
// 옵셔널 Person 타입인 cheon 변수 선언
cheon.contacts.email
//email에 접근시 위와 같이 하면 cheon은 옵셔널 타입이기 때문에 오류가 뜸
cheon?.contacts.email
// 위 처럼 접근해야 접근이 가능함 위와같은 방법이 바로 옵셔널 체이닝
❓ 1. 어떻게 출력이 될까용?
var myBoyFriend: String? = "장석우"
print(myBoyFriend)

var mySecondBoyFriend: String? = nil
print(mySecondBoyFriend)

// 출력 형태 
//	   Optional("장석우")
//		 nil

Optional Type을 Unwrapping 혹은 Binding을 거치지 않고 출력하면 Optional(”~~”) 형태로 출력 됨

Optonal Type의 변수이기 때문에 nil으로 지정 가능!

❓ 2. if let과 guard let의 차이점을 표로 설명하시오!

guard let과 if let은 모두 Optional Biinding을 사용하여 안전하게 변수나 상수를 추출하는 방법이지만 두 구문은 몇 가지 차이점이 있습니다 !

guard letif let
사용 목적코드의 가독성과 유지보수성을 높이기 위해 사용조건 분기문에서 바인딩된 값의 nil 여부에 따른 코드 실행 여부 결정
코드 블록 위치코드 블록의 시작 부분에 사용조건문 내에서 사용
바인딩된 값이 nil인 경우빠른 종료를 수행하여 바로 다음 코드 블록으로 이동조건문 내의 else 블록으로 이동
profile
응애 난 애기 개발자..

0개의 댓글