Swift Enum๊ณผ Optional
iOS ๐Ÿ”ฅ/Swift

Swift Enum๊ณผ Optional

์Šคํƒ ํฌ๋“œ ๋Œ€ํ•™๊ต ๊ฐ•์˜์˜ ์ผ๋ถ€๋ฅผ ํ•ด์„ํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.
์กฐ๊ธˆ์ด๋ผ๋„ ์˜๋ฏธ๊ฐ€ ์ž˜๋ชป ์ „๋‹ฌ๋  ๊ฒƒ ๊ฐ™์€ ๋ถ€๋ถ„์€ ์˜์–ด๋ฅผ ๊ทธ๋Œ€๋กœ ์ผ์Šต๋‹ˆ๋‹ค.
์ง์—ญ์ด๋ผ, ๋ฐ˜๋ง๋กœ ์ผ๋Š”๋ฐ ์–‘ํ•ด ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. :)

Enum

Associated Data๋ฅผ ๋ชจ์•„๋†“๋Š” ๊ณณ์ด๋ฉฐ, struct์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ VALUE TYPE์ด๋‹ค.

enum FastFood {

    case hamburger(numberOfPatties: Int)

    case drink(String, ounces: Int)

    case cookie

    // method๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. 
    func isHamburger(number: Int) -> Bool { 
        switch self {
            case .hamburger:
                return true
            default:
                return false
        }
    }
    // ์ €์žฅ ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ–์„ ์ˆ˜ ์—†์ง€๋งŒ, ๊ณ„์‚ฐ ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
    var calories: Int {
        // ์นผ๋กœ๋ฆฌ๋ฅผ ๊ณ„์‚ฐ
    }

    //mutating ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์žฌํ• ๋‹น ํ•  ์ˆ˜ ์žˆ๋‹ค.
    //mutating ํ‚ค์›Œ๋“œ๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ๋Š” 'VALUE TYPE'์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 
    mutating func switchToBeingCookie {
        self = .cookie
    }

}

// Set
let menu: FastFood = FastFood.hamburger(patties:2)
let menu2: FastFood = .cookie // Type Inference

// ์ƒํƒœ์ฒดํฌ
switch menu {
    case .hamburger: print("burger")
    case .drink: print("dirnk")
    case .cookie: break // If you don't want to do anything
}

// Switch๋ฌธ์—์„œ ๋ฐ˜๋“œ์‹œ ALL POSSIBLE CASES๋ฅผ ๋‹ค๋ฃจ์–ด์•ผ ํ•จ.
// ์‹ซ๋‹ค๋ฉด default

switch menu {
    case .hamburger: print("burger")
    default: print("not burger")    
}

// ์—ฐ๊ด€๋œ ๋ฐ์ดํ„ฐ๋Š” ์–ด๋–ป๊ฒŒ ๊ฐ€์ ธ์˜ค๋Š”๊ฐ€?
// "let" syntax๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
// ์„ ์–ธ๊ณผ๋Š” ๋‹ค๋ฅธ์ด๋ฆ„์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ์„ ์ฃผ๋ชฉํ•ด๋ผ.
switch menu {
    case .hamburger(let pattyCount): print("\(pattyCount) patties!")
    // ๋งŒ์•ฝ ์ƒ๊ด€์—†๋Š” ๋ฐ์ดํ„ฐ๋ผ๋ฉด _ ๋ฅผ ์‚ฌ์šฉํ•ด๋ผ.
    case .drink(_, let ounces): print("\(ounces)")
    default: print("not burger")
}

Optional

์˜ต์…”๋„์€ Enum์ด๋ฉฐ, Swift์—์„œ ์™„์ „ํ•œ ํƒ€์ž…์ด๋‹ค!

nil ⇒ not set

? ⇒ Optional์„ ์„ ์–ผํ•  ๋•Œ, ๊ฐ’์„ ์ถ”์ถœํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

! ⇒ Optional ๋ฐ์ดํ„ฐ๋ฅผ unwrapํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•  ๋•Œ if ํ‚ค์›Œ๋“œ๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

๋งŒ์•ฝ ! ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ–ˆ๋‹ค๋ฉด, ์ ‘๊ทผ ์‹œ ๊ฐ•์ œ ์ถ”์ถœํ•จ์„ ์˜๋ฏธํ•œ๋‹ค.

?? ⇒ Optional์ด not set์ผ ๋•Œ default value๋ฅผ ํ‘œํ˜„ํ•œ๋‹ค.

enum Optional <T> {
    case None
    case Some(<T>)
}
var hello: String? // var hello: Optional<String> = .none
var hello: String? = "hello" // var hello: Optional<String> = .some("hello")
var hello: String? = nil // var hello: Optional<String> = .none

// Optional Chaining
let y = x?.foo()?.bar?.z

unwraping ํ•˜๋Š” ๊ณผ์ •์€ ๋‹ค์Œ์˜ switch๋ฌธ๊ณผ ๊ฐ™๋‹ค ๋ณด๋ฉด ๋œ๋‹ค.

์กฐ๊ธˆ ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ๋Š”๋ฐ

var hello: Int?

์˜ ์ž๋ฃŒํ˜•์ด ๋ฌด์—‡์ด๋ƒ๊ณ  ๋ฌผ์–ด ๋ณด์•˜์„ ๋•Œ, Int๊ฐ€ ์•„๋‹Œ Optional Type์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ํŽธํ•˜๋‹ค. (์กฐ๊ธˆ ๋” ์„ธ๋ถ€์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด Optional String ํƒ€์ž…)