상세 컨텐츠

λ³Έλ¬Έ 제λͺ©

[ Swift 기초 문법 ] μ˜΅μ…”λ„ νƒ€μž…(Optional Types) / Unwrapping / μ˜΅μ…”λ„ 바인딩(Optional Binding)

🍎 iOS/Swift

by AHN.Jihyeon 2024. 5. 2. 21:24

λ³Έλ¬Έ

 


 

πŸ’¬  Introduction

πŸ’¬

λ‹€λ₯Έ μ–Έμ–΄μ—μ„œλŠ” μ—†λŠ” μƒˆλ‘œμš΄ νƒ€μž…μœΌλ‘œ νƒ€μž… 뒀에 λ¬ΌμŒν‘œ(?)만 λΆ™μ—¬ μ£Όλ©΄ λœλ‹€.

 

μ•± μž‘λ™ μ‹œ λ©”λͺ¨λ¦¬ 곡간에 값이 μ—†μœΌλ©΄ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

μ΄λŠ” 앱이 κΊΌμ§€κ²Œ λ˜λ―€λ‘œ 맀우 μœ„ν—˜ν•œ μ—λŸ¬μ΄λ‹€. 

 

ex)

λ„€νŠΈμ›Œν¬μ—μ„œ κ°€μ Έ 온 κ°’μœΌλ‘œ μ΄ˆκΈ°ν™” ν•œλ‹€κ³  ν•˜λ©΄ 접속이 λ˜μ–΄ μžˆμ§€ μ•Šκ±°λ‚˜

쀑간에 연결이 끊겨 버리면 값을 μ €μž₯ν•  수 μ—†κ²Œ λœλ‹€.

이런 경우 값이 μ €μž₯λ˜μ–΄ μžˆμ§€ μ•ŠλŠ”λ° λ„Œμ˜΅μ…”λ„ νƒ€μž…μ€ 값을 λ°˜λ“œμ‹œ 가지고 μžˆμ–΄μ•Ό ν•˜λŠ”λ°

μ—†κΈ° λ•Œλ¬Έμ— μ—λŸ¬κ°€ λ°œμƒν•˜κ²Œ λœλ‹€. 

 

λ”°λΌμ„œ λ³€μˆ˜μ™€ μƒμˆ˜λŠ” 값을 읽기 전에 λ°˜λ“œμ‹œ μ΄ˆκΈ°ν™” ν•΄μ•Ό ν•œλ‹€.

이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ μž„μ‹œμ μΈ νƒ€μž…μ„

λ©”λͺ¨λ¦¬ 곡간에 λ‹΄μ•„λ‘λŠ” κ°œλ…μ΄ μ˜΅μ…”λ„ νƒ€μž…μ΄λ‹€. 

 

 

항상 νƒ€μž…μ— λ§žλŠ” 값을 가지고 μžˆμ–΄μ•Ό ν•œλ‹€. 

-> λ„Œμ˜΅μ…”λ„ νƒ€μž… (Non- optional Type)

 

* μ˜΅μ…”λ„ νƒ€μž…μ΄ λ„Œμ˜΅μ…”λ„ νƒ€μž…λ³΄λ‹€ 더 넓은 λ²”μœ„μ— ν•΄λ‹Ήλœλ‹€. 

 

 

 

πŸ”Ž  1 . μ˜΅μ…”λ„ νƒ€μž…(Optional Types) 


λ„Œμ˜΅μ…”λ„ νƒ€μž…μ— ?λ₯Ό 뢙이면 μ˜΅μ…”λ„ νƒ€μž…μ΄ λœλ‹€.

var num1: Int? = 3            //κ°„νŽΈ 문법
var num2: optional<Int> = 5   //μ •κ·œ 문법
var num3 = nil                //잘λͺ»λœ 문법 - νƒ€μž… 좔둠이 λΆˆκ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— κΌ­ μ •ν™•ν•œ νƒ€μž… λͺ…μ‹œ

print(num1) // 좜λ ₯κ°’ : optional(3)

//================================

var name: String?
//name = "jihyeon"

print(name) // 좜λ ₯κ°’ : nil <- μžλ™μœΌλ‘œ nil둜 μ΄ˆκΈ°ν™”λ¨

: μ •μˆ˜ + nil(μž„μ‹œμ μΈ νƒ€μž…, 값이 μ—†μŒμ„ μ•Œλ €μ£ΌλŠ” μž„μ‹œμ μΈ ν‘œν˜„)

 

μ˜΅μ…”λ„μ€ 값이 없을 μˆ˜λ„ μžˆλŠ” 경우인 nil이 ν¬ν•¨λœ νƒ€μž…μ΄λ‹€. 

값이 μ—†μœΌλ©΄ μžλ™μœΌλ‘œ nilμ΄λΌλŠ” μž„μ‹œμ μΈ νƒ€μž…μœΌλ‘œ μ΄ˆκΈ°ν™”κ°€ 되기 λ•Œλ¬Έμ— 

λ©”λͺ¨λ¦¬μ— 접근해도 μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€. 

 

* λ‹€λ₯Έ μ–Έμ–΄μ—μ„œμ˜ null은 μ‹€μ œλ‘œ 값이 μ—†μŒμ„ μ˜λ―Έν•˜λŠ” 차이점이 μžˆλ‹€.

* Int(μ •μˆ˜ν˜•)μ™€λŠ” μ „ν˜€ λ‹€λ₯Έ νƒ€μž…μ΄λ‹€.

 

 

var num1: Int? = nil
num = 10

print(num1) // Optional(10)   : μ˜΅μ…”λ„ νƒ€μž…
print(num1) // 10             : λ„Œμ˜΅μ…”λ„ νƒ€μž…

var num2: Int? = 5

print(num1+num2)     // 였λ₯˜ : μ˜΅μ…”λ„ νƒ€μž…λΌλ¦¬μ˜ 연산은 λΆˆκ°€


//======================================
let num1: Int? = nil    // 였λ₯˜ : μ˜΅μ…”λ„ νƒ€μž…μ€ 항상 var둜 μ„ μ–Έν•œλ‹€.   
                        // nil은 값이 없을 μˆ˜λ„ μžˆλŠ” κ°’μ΄λ―€λ‘œ 값이 λ³€ν•  μˆ˜λ„ μžˆμ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έ!!

 

 

πŸ”Ž  2. μ˜΅μ…”λ„ κ°’ μΆ”μΆœ(Unwrapping) 


: 값을 μΆ”μΆœν•œλ‹€. 단, nil이 μ•„λ‹Œ κ²½μš°μ—λ§Œ λ²—κΈΈ 수 μžˆλ‹€. 

 

μ˜΅μ…”λ„μ€ νŠΉλ³„ν•œ λ°©μ‹μœΌλ‘œ 값을 μ €μž₯ν•˜κ³  있기 λ•Œλ¬Έμ—

값을 μ‚¬μš©ν•˜λ €λ©΄ 값을 κΊΌλ‚΄μ•Όν•˜λŠ”λ° 이런 μž‘μ—…μ„ μ–Έλž©ν•‘μ΄λΌκ³  ν•œλ‹€.

μ΄λ•Œ, μΆ”μΆœλœ κ°’μ˜ νƒ€μž…μ€ λ„Œμ˜΅μ…”λ„ νƒ€μž…μ΄ λœλ‹€.

 

μ•„λž˜λŠ” 값을 μΆ”μΆœν•˜λŠ” 방식이닀.

 

1)  κ°•μ œ μΆ”μΆœ(Forced Unwrapping)

: μ˜΅μ…”λ„ ν‘œν˜„μ‹μ— !만 뢙이면 λœλ‹€. 

// κ°•μ œ μΆ”μΆœ : 값이 μžˆλŠ” 것이 ν™•μ‹€ν•  λ•Œ μ‚¬μš©

var num1: Int? = 10
var num2: Int?

print(num1!)   // 좜λ ₯ : 10
print(num2!)   // μ—λŸ¬ λ°œμƒ -> 값이 μ‹€μ œλ‘œ μ—†λŠ”λ° κ°•μ œλ‘œ μΆ”μΆœν–ˆκΈ° λ•Œλ¬Έ

 

 

πŸ“Œ 값이 μ—†λŠ” 경우 κ°•μ œ μΆ”μΆœμ„ ν•˜κ²Œ 되면 fatal errorκ°€ λ°œμƒν•  수 μžˆλ‹€.

μ΄λ•Œ 앱이 λ°”λ‘œ κΊΌμ§€κ²Œ λ˜λ―€λ‘œ ν•„μš”ν•œ κ²½μš°μ—λ§Œ μ œν•œμ μœΌλ‘œ μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€. 

κ°•μ œμΆ”μΆœμ„ μ•ˆμ „ν•˜κ²Œ μ‚¬μš©ν•˜λ €λ©΄ 값을 κΊΌλ‚΄κΈ° 전에 값이 μžˆλŠ”μ§€ ν™•μΈν•˜λŠ” 것이 μ€‘μš”ν•˜λ‹€.

 

 

 

2)  if문으둜 nil이 μ•„λ‹Œ 것을 확인 ν›„ κ°•μ œ μΆ”μΆœ

var num: Int?    // nil

// if문으둜 값이 μžˆλŠ”μ§€ 확인 ν›„ μΆ”μΆœ
if num != nil {
	print(num)   // 좜λ ₯ μ•ˆλ¨
}

 

 

 

3) 🌟 μ˜΅μ…”λ„ 바인딩 (Optional Binding) -  ifλ¬Έ, whileλ¬Έ, guardλ¬Έμ—μ„œ μ‚¬μš©

:  κ°•μ œμΆ”μΆœ λ³΄λ‹€λŠ” μ˜΅μ…”λ„ 바인딩을 μ‚¬μš©ν•΄ 값을 μ•ˆμ „ν•˜κ²Œ μΆ”μΆœν•œλ‹€.

λ©”λͺ¨λ¦¬ 곡간에 μžˆλŠ” μ˜΅μ…”λ„ 값이 μƒμˆ˜μ— λ‹΄κΈ΄λ‹€λ©΄(nil 값이 μ•„λ‹ˆλΌλ©΄) μ½”λ“œ λ‚΄λΆ€ μ‹€ν–‰ν•œλ‹€

var num1: Int?       // nil
var num2: Int? = 10  // optional(10)
 


// if let 바인딩 ==============================
if let n1 = num1 {    // μƒμˆ˜μ— λ‹΄κΈ΄λ‹€λ©΄ == nil이 μ•„λ‹ˆλ‹€
	print(n1)         // 좜λ ₯ μ•ˆλ¨
}

if let n2 = num2 {
	print(n2)         // 좜λ ₯ : 10 
}


// guard let 바인딩 ==============================
func sayHello(name: String?) {          // 값이 μžˆμ„ μˆ˜λ„ 없을 μˆ˜λ„ 있음 
	guard let n = name else {return}    // 값이 μžˆλŠ” κ²½μš°μ—λ§Œ μƒμˆ˜ n에 λ‹΄κΈ°κ³  μ•„λž˜ μ½”λ“œ μ‹€ν–‰ 
    print(n)                            // μ΄λ•Œ n은 optional("hi") νƒ€μž…μ΄ nμ—μ„œ λ²—κ²¨μ €μ„œ λ‹΄κΈ΄λ‹€λ©΄ 
}

sayHello("hi")    // 좜λ ₯ : hi

 

 

μ˜΅μ…”λ„ ν‘œν˜„μ‹μ„ ν‰κ°€ν–ˆλŠ”λ° 값이 μ €μž₯λ˜μ–΄ μžˆλ‹€λ©΄ 값을 μ–Έλž˜ν•‘ν•΄μ„œ μƒμˆ˜μ— μ €μž₯ν•œλ‹€. 이 μƒνƒœκ°€ 바인딩이 μ„±κ³΅ν•œ 것.

 

λ°˜λŒ€λ‘œ, 값이 μ—†λ‹€λ©΄(nil이 μ €μž₯λ˜μ–΄ μžˆλ‹€λ©΄) 바인딩에 μ‹€νŒ¨ν•œ 것.

μ΄λ•Œ ifλ¬Έκ³Ό while문은 λ‹€μŒ λ¬Έμž₯으둜 μ œμ–΄λ₯Ό λ„˜κΈ°κ³  guardλ¬Έμ—μ„œλŠ” else 블둝이 μ‹€ν–‰λ˜κ³  μŠ€μ½”ν”„κ°€ κ±°κΈ°μ„œ λλ‚œλ‹€.

 

μ˜΅μ…”λ„ ν‘œν˜„μ‹μ— 값이 μ €μž₯λ˜μ–΄ μžˆμ„ λ•Œλ§Œ μ–Έλž©ν•‘ ν•˜κΈ° λ•Œλ¬Έμ— κ°•μ œ μΆ”μΆœ ν•  λ•Œ λ°œμƒν–ˆλ˜ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.

μ½”λ“œμ—μ„œ λ°œμƒν•  수 μžˆλŠ” μ˜΅μ…”λ„ μ—λŸ¬λ₯Ό ν”Όν•  수 μžˆλ‹€.

 

if / while λ¬Έμ—μ„œ μ˜΅μ…”λ„ λ°”μΈλ”©μœΌλ‘œ μ„ μ–Έν•œ μƒμˆ˜λŠ” λ°”λ‘œ μ΄μ–΄μ§€λŠ” 둜컬 μŠ€μ½”ν”„μ—μ„œλ§Œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€. 

 

 

 

4) λ‹ μ½”μ–Όλ ˆμ‹± μ—°μ‚°μž ν™œμš© (Nil-Coalescing)

μ˜΅μ…”λ„ νƒ€μž… ??(λ¬ΌμŒν‘œ2개) 뒀에 μ˜΅μ…”λ„ 값이 nil일 경우 κΈ°λ³Έκ°’μœΌλ‘œ μ‚¬μš©λ  값을 μ λŠ”λ‹€.

μ–΄λ– ν•œ κ²½μš°μ—λ„ 값이 μ—†λŠ” κ²½μš°κ°€ μ—†λ‹€. 

κΈ°λ³Έ 값을 μ œμ‹œν•  수 μžˆμ„ λ•Œ μ‚¬μš©ν•œλ‹€. 

μΆ”μΆœ ν›„ μƒˆλ‘œμš΄ λ³€μˆ˜μ— λ‹΄κΈ°λ©΄ λ„Œμ˜΅μ…”λ„ νƒ€μž…μœΌλ‘œ λ‹΄κΈ΄λ‹€. 

 

얼핏, 삼항연산와 λΉ„μŠ·ν•œλ° μ‹€μ œλ‘œλ„ μ‚Όν•­μ—°μ‚°μžλ‘œλ„ μ‚¬μš©ν•  수 μžˆλ‹€.

var str:String? = "jihyeon"

print(str ?? "hello")   // 좜λ ₯ : jihyeon

str = nil

print(str ?? "hello")   // 좜λ ₯ : hello

 

 

 

πŸ”— Reference 
- https://www.inflearn.com/course/lecture?courseSlug=%EC%8A%A4%EC%9C%84%ED%94%84%ED%8A%B8-%EB%AC%B8%EB%B2%95-%EB%A7%88%EC%8A%A4%ED%84%B0-%EC%8A%A4%EC%BF%A8&unitId=86559

https://www.youtube.com/watch?v=UwHB4sM5tJA

 

κ΄€λ ¨κΈ€ 더보기