์ด๊ฑฐํ (Enum)
์ด๊ฑฐํ(Enum)์ ์ฐ๊ด๋ ๊ฐ๋ค์ ํ๋์ ํ์ ์ผ๋ก ๋ฌถ์ด ํํํ๋ ์๋ฃํ์ ๋๋ค.
Swift์์๋ ๋จ์ํ ๊ฐ ๋ชฉ๋ก์ ๋์ด, ํ์ ์์ ์ฑ๊ณผ ํํ๋ ฅ์ ๋ชจ๋ ๊ฐ์ถ ๊ตฌ์กฐ๋ก ์ฌ์ฉ๋๋ฉฐ,
๊ฐ case๋ ๋ ๋ฆฝ์ ์ธ ๊ฐ์ผ๋ก ๋์ํ๊ณ ํ์์ ๋ฐ๋ผ ์ฐ๊ด๊ฐ(Associated Value) ์ ์ ์ฅํ ์ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ ์ด๊ฑฐํ์ ์ฌ์ฉํ ๊น์?
์ด๊ฑฐํ์ ๋น์ทํ ์ฑ๊ฒฉ์ ์ฌ๋ฌ ๊ฐ์ ํ๋์ ๋ฒ์ฃผ๋ก ๋ฌถ์ด ์ฝ๋์ ์๋ฏธ๋ฅผ ๋ช ํํ ํ๊ณ , ์๋ชป๋ ๊ฐ์ด ์ ์ฅ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
๋ํ Enum์ ๋ฉ์๋๋ฅผ ์ ์ํ๊ฑฐ๋ ํ๋กํ ์ฝ์ ์ฑํํ ์ ์๋ ํ์ฅ ๊ฐ๋ฅํ ํ์ ์ผ๋ก,
ํ๋ก๊ทธ๋จ์ ์ํ๋ ์ข ๋ฅ๋ฅผ ๋ช ํํ๊ฒ ๊ตฌ๋ถํ๊ณ ์ฝ๋๋ฅผ ์์ ํ๊ฒ ์ ์งํ๋ ๋ฐ ํ์ฉ๋ฉ๋๋ค!
๐ ์ด๊ฑฐํ์ ์ฌ์ฉํ๋ ์ด์
์ด๊ฑฐํ์ ์ฌ์ฉํ์ง ์๊ณ ๋จ์ํ String์ด๋ Int๋ก ์ํ๋ฅผ ์ ์ฅํ๋ฉด, ์๋ชป๋ ์ ๋ ฅ์ด๋ ์คํ๋ก ์ธํ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค.
์๋ฅผ ๋ค์ด, ํ์ด๋ง๊ตฌ์ผ(Hilingual) ์ฑ์์ iOS ํํธ์ ํ์์ ๊ด๋ฆฌํ๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
let iosMember1 = "zero"
let iosMember2 = "one"
let iosMember3 = "tew" // ์คํ ๋ฐ์
์ด์ฒ๋ผ ๋ฌธ์์ด๋ก ๊ด๋ฆฌํ ๊ฒฝ์ฐ "yaungjuuu"์ฒ๋ผ ์คํ๊ฐ ๋๋ ์ปดํ์ผ๋ฌ๋ ์ค๋ฅ๋ฅผ ์ธ์ํ์ง ๋ชปํฉ๋๋ค.
์ด๋ฐ ๋ฌธ์ ๋ ๋ฐํ์ ์์ ์์์ผ ๋๋ฌ๋๊ธฐ ๋๋ฌธ์ ์ ์ง๋ณด์์ ๋ถ๋ฆฌํฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๊ฑฐํ์ ์ฌ์ฉํ๋ฉด ์ด๋จ๊น์?
๋ฏธ๋ฆฌ ์ ์๋ ๊ฐ๋ง ์ ํํ ์ ์์ผ๋ฏ๋ก ์คํ๋ ์๋ชป๋ ์ ๋ ฅ์ด ์์ฒ์ ์ผ๋ก ์ฐจ๋จ๋ฉ๋๋ค!
๋ํ ์ฝ๋์ ์๋ฏธ๊ฐ ๋ช ํํด์ ธ ๊ฐ๋ ์ฑ๊ณผ ์์ ์ฑ์ ๋์์ ํ๋ณดํ ์ ์์ต๋๋ค.
์์๋ฅผ ํ๋ฒ ์ดํด๋ด ์๋ค.
enum IosMember {
case zero
case one
case two
}
var member: IosMember = .zero
์ด์ member์๋ .youngseo, .nayeon, .youngju ์ธ์ ๊ฐ์ ๋ค์ด๊ฐ ์ ์์ต๋๋ค.
Swift์ ํ์ ์์คํ ์ด ์ปดํ์ผ ๋จ๊ณ์์ ๊ฐ์ ๊ฒ์ฌํ๋ฏ๋ก, ์๋ชป๋ ์ ๋ ฅ์ ์ฆ์ ์ค๋ฅ๋ก ์ฒ๋ฆฌ๋๊ฒ ์ฃ .
์ฆ, ์ด๊ฑฐํ์ ์ ํด์ง ์ ํ์ง ์์์๋ง ์์ ํ๊ฒ ๊ฐ์ ๋ค๋ฃจ๋๋ก ๋ณด์ฅํ๋ ์๋ฃํ์์ ์ ์ ์์ต๋๋ค.
๐ ์์๊ฐ (Raw Value)
1. ์์๊ฐ์ด ์๋ ์ด๊ฑฐํ
์์๊ฐ์ด๋ ๊ฐ case์ ๊ณ ์ ๋ ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํ๋ ๊ฒ์ ๋งํฉ๋๋ค.
์์๊ฐ์ด ์๋ ์ด๊ฑฐํ์ ๊ทธ์ค์์๋ ๊ฐ์ฅ ๋จ์ํ ํํ๋ก, ๊ฐ case์ ๋ณ๋์ ๊ฐ์ ์ง์ ํ์ง ์์ต๋๋ค.
์ฆ, ์๋์ฒ๋ผ ๋จ์ํ ์ํ๋ ๋จ๊ณ๋ง ๊ตฌ๋ถํ ๋ ์ฌ์ฉํ๋ ์ด๊ฑฐํ์ ๋๋ค.
enum HomeViewState {
case idle // ์๋ฌด ๋์๋ ์๋ ์ํ
case loading // ๋ฐ์ดํฐ ๋ก๋ฉ ์ค
case success // ๋ถ๋ฌ์ค๊ธฐ ์ฑ๊ณต
case failure // ๋ถ๋ฌ์ค๊ธฐ ์คํจ
}
์ ์ฝ๋๋ฅผ ์ผํ๋ฅผ ์ด์ฉํ์ฌ ํ ์ค๋ก ํํํ ์๋ ์์ต๋๋ค!
enum HomeViewState { case idle, loading, success, failure }
์ฌ์ฉ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
var currentState: HomeViewState = .loading
์ด์ฒ๋ผ ์ด๊ฑฐํ ์์ฒด๊ฐ ํ๋์ ํ์ ์ผ๋ก ์ธ์๋๋ฉฐ, . ๋ฌธ๋ฒ์ ํตํด ๋ฏธ๋ฆฌ ์ ์๋ case๋ง ์ ๊ทผํ ์ ์์ต๋๋ค.
์๋์น ์์ ๊ฐ์ ๋์ ์ด ๋ถ๊ฐ๋ฅํ๋ ์ค๋ฅ๋ฅผ ์ค์ผ ์ ์๊ฒ ์ฃ !
2. ์์๊ฐ์ด ์๋ ์ด๊ฑฐํ
์ด๊ฑฐํ์ ๊ฐ case์ ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํ ์๋ ์์ต๋๋ค.
์ด๋ ์ง์ ๋๋ ๊ฐ์ด ์์๊ฐ์ด๋ฉฐ, ๋ชจ๋ case๊ฐ ๋์ผํ ํ์ ์ ๊ฐ ์ ๊ฐ์ ธ์ผ ํฉ๋๋ค.
Swift์์ Raw Value๋ก ์ฌ์ฉํ ์ ์๋ ํ์ ์ Int, Character, String ์ธ ๊ฐ์ง์ ๋๋ค.
ํ๋ํ๋ ์ฐจ๋ก๋๋ก ์์๋ณผ๊ฒ์!
(1) Intํ ์์๊ฐ
๊ฐ์ฅ ์์ฃผ ์ฌ์ฉ๋๋ ํํ๋ก, Raw Value๋ฅผ Int๋ก ์ง์ ํ๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ์ฒซ ๋ฒ์งธ case๋ถํฐ 0๋ถํฐ ์์ํด 1์ฉ ์๋์ผ๋ก ์ฆ๊ฐ์ํต๋๋ค.
enum HTTPStatusCode: Int {
case success
case badRequest
case unauthorized
case notFound
}
์์ ์์์์ success๋ 0, badRequest๋ 1, unauthorized๋ 2, notFound๋ 3์ ๋๋ค.
์๋์ฒ๋ผ ์ง์ ๊ฐ์ ์ง์ ํ ์๋ ์์ต๋๋ค.
enum HTTPStatusCode: Int {
case success = 200
case badRequest = 400
case unauthorized = 401
case notFound = 404
}
๊ทธ๋ ๋ค๋ฉด, ๋ง์ง๋ง case์ ๊ฐ์ ์ง์ ํ์ง ์์ผ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
enum HTTPStatusCode: Int {
case success = 200
case badRequest = 400
case unauthorized = 401
case notFound
}
๋ต์ 402์ ๋๋ค! ์ปดํ์ผ๋ฌ๋ ์ง์ ๋ case ์ดํ์ ๊ฐ์ด ์์ผ๋ฉด ์ด์ case์ Raw Value์ +1์ ์๋์ผ๋ก ๋ํด์ค๋๋ค.
๋ฐ๋ผ์ notFound์๋ 401 ๋ค์ ๊ฐ์ธ 402๊ฐ ๋ค์ด๊ฐ๊ฒ ๋๋๊ฑฐ์ฃ .
โ ๏ธ ๋ง์ฝ Raw Value ํ์ ์ด Double์ด๋ Float์ด๋ผ๋ฉด,์ปดํ์ผ๋ฌ๋ ์๋์ผ๋ก “์ด์ ๊ฐ + 1”์ ๊ณ์ฐํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ๋ชจ๋ case์ ๋ํด ๊ฐ์ ์ง์ ์ง์ ํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด “Cannot infer raw value” ์๋ฌ๊ฐ ๋ฐ์ํด์!
(2) Characterํ ์์๊ฐ
Character ํ์ ์ ๋ชจ๋ case์ ์ง์ ๊ฐ์ ์ง์ ํด์ผ ํฉ๋๋ค.
ํ๋๋ผ๋ ์๋ต๋๋ฉด ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
enum ShortcutKey: Character {
case save = "S"
case open = "O"
case quit = "Q"
}
์ด ๊ฒฝ์ฐ ShortcutKey.save.rawValue๋ "S"์ ๋๋ค.
โ ๏ธ Character ํ์ ์ ๋ฌธ์ ๋จ์๋ก๋ง ์ ์ฅ๋๋ฏ๋ก, ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก ๊ฐ์ ์ฆ๊ฐ์ํฌ ์ ์์ต๋๋ค.
"A" ๋ค์ "B"๋ก ๋์ด๊ฐ๋ ์์ ๊ณ์ฐ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
(3) Stringํ ์์๊ฐ
String ํ์ ์ Character์ ๋ฌ๋ฆฌ Raw Value๋ฅผ ์๋ตํ๋ฉด case ์ด๋ฆ์ด ๊ทธ๋๋ก ๋ฌธ์์ด ๊ฐ์ผ๋ก ์๋ ์ง์ ๋ฉ๋๋ค.
enum APIEndpoint: String {
case diaryList
case userProfile
case updateNickname
}
- APIEndpoint.diaryList.rawValue → "diaryList"
- APIEndpoint.userProfile.rawValue → "userProfile"
์ด ๋ฐฉ์์ ์๋ฒ ํต์ ์ ์๋ํฌ์ธํธ ์ด๋ฆ์ด๋ ๋ฆฌ์์ค ๊ฒฝ๋ก๋ฅผ ํํํ ๋ ์์ฃผ ์ฌ์ฉ๋๋๋ฐ์~
case ์ด๋ฆ๊ณผ ์ค์ ๋ฌธ์์ด ๊ฐ์ด ์ผ์นํ๋ฏ๋ก, ์คํ๋ฅผ ๋ฐฉ์งํ๋ฉด์๋ ์ฝ๋๋ฅผ ๋ ๊น๋ํ๊ฒ ์ ์งํ ์ ์๊ฒ ์ฃ !
3. Raw Value ์ ๊ทผ ๋ฐ ์ด๊ธฐํ
์ด๊ฑฐํ์ ์ง์ ํ ์์๊ฐ(Raw Value)์ rawValue ์์ฑ์ ํตํด ์ฝ๊ฒ ๊บผ๋ผ ์ ์์ต๋๋ค.
enum Fruit: String {
case apple
case banana
case orange
}
print(Fruit.banana.rawValue) // "banana"
์ด๋ ๊ฒ ํ๋ฉด banana case์ ๋ฌธ์์ด ๊ฐ "banana"๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
Raw Value๋ฅผ ์ด์ฉํด ์ด๊ฑฐํ ์ธ์คํด์ค๋ฅผ ์์ฑํ ์๋ ์์ต๋๋ค.
์ฆ, ๋ฌธ์์ด์ ํตํด ํด๋น case๋ฅผ ์ฐพ์ ๋ง๋๋ ๋ฐฉ์์ ๋๋ค.
let selectedFruit = Fruit(rawValue: "orange")
print(selectedFruit) // Optional(Fruit.orange)
"orange"๊ฐ ์ค์ ์กด์ฌํ๋ case์ด๊ธฐ ๋๋ฌธ์ ์ ์์ ์ผ๋ก ์ธ์คํด์ค๊ฐ ๋ง๋ค์ด์ง๋๋ค.
๋ค๋ง, ์กด์ฌํ์ง ์๋ ๊ฐ์ ์ ๋ฌํ๋ฉด nil์ด ๋ฐํ๋ฉ๋๋ค.
let invalidFruit = Fruit(rawValue: "melon")
print(invalidFruit) // nil
๊ทธ๋์ Raw Value๋ฅผ ํตํ ์ด๊ธฐํ์ ๋ฐํ ํ์ ์ ํญ์ ์ต์ ๋(Optional) ์ ๋๋ค!
์กด์ฌํ์ง ์๋ ๊ฐ์ด ๋ค์ด์ฌ ์๋ ์๊ธฐ ๋๋ฌธ์, Swift์์๋ ํ๋ก๊ทธ๋จ์ด ๋ฉ์ถ์ง ์๊ณ ์์ ํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋๋ก ์ต์ ๋ ํํ๋ก ๋ฐํํ๋ต๋๋ค.
๐ ์ฐ๊ด๊ฐ (Associated Values)
Raw Value๋ ๋ชจ๋ case๊ฐ ๊ฐ์ ํ์ ์ ๊ฐ์ ๊ฐ์ง๋๋ค.
ํ์ง๋ง ์ค์ ๋ก๋ case๋ง๋ค ์๋ก ๋ค๋ฅธ ์ ๋ณด๋ฅผ ํจ๊ป ์ ์ฅํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ฃ .
์๋ฅผ ๋ค์ด, ์์ ์ฃผ๋ฌธ ์ํฉ์ ์๊ฐํด๋ณผ๊น์? ์์๋ง๋ค ์ถ๊ฐ ์ต์ ์ด ๋ค๋ฅผ ์ ์์ต๋๋ค.
ํผ์๋ ์ฌ์ด์ฆ๊ฐ ํ์ํ๊ณ , ์๋ฃ๋ ์ผ์ ์ ๋ฌด๊ฐ ํ์ํ๊ฒ ์ฃ ?
์ด๋ด ๋ ์ฌ์ฉํ๋ ๊ฒ ๋ฐ๋ก ์ฐ๊ด๊ฐ(Associated Values) ์ ๋๋ค.
์ฐ๊ด๊ฐ์ ๊ฐ case์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์ ์ฅํ ์ ์์ต๋๋ค!
1. ์ฐ๊ด๊ฐ ์ ์ธ
case ์ ๊ดํธ ์์, ๊ทธ case์ ํ์ํ ์ ๋ณด๋ฅผ ๋ด์ ์ ์์ต๋๋ค.
enum Order {
case pizza(size: String)
case drink(ice: Bool)
case dessert(name: String)
}
2. ์ฐ๊ด๊ฐ ์ธ์คํด์ค ์์ฑ
case๋ฅผ ์์ฑํ ๋ ๊ดํธ ์์ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
let order1 = Order.pizza(size: "L")
let order2 = Order.drink(ice: true)
let order3 = Order.dessert(name: "cheesecake")
์ด์ ๊ฐ ์ฃผ๋ฌธ์ ํ๋์ ํ์ (Order) ์์์ ์๋ก ๋ค๋ฅธ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๊ฒ ๋๊ฒ ์ฃ .
3. Switch๋ฌธ์ผ๋ก ๊ฐ ๊บผ๋ด๊ธฐ
switch๋ฌธ์ ์ฌ์ฉํด ๊ฐ case์ ๊ฐ์ ๊บผ๋ด์ ์ธ ์ ์์ต๋๋ค.
switch order2 {
case .pizza(let size):
print("ํผ์ ์ฌ์ด์ฆ๋ \\(size)์
๋๋ค.")
case .drink(let ice):
print(ice ? "์ผ์ ์๋ ์๋ฃ ์ฃผ๋ฌธ" : "์ผ์ ์๋ ์๋ฃ ์ฃผ๋ฌธ")
case .dessert(let name):
print("๋์ ํธ: \\(name)")
}
4. if-case ๊ตฌ๋ฌธ
ํน์ case๋ง ํ์ธํ๊ณ ์ถ์ ๋ if case๊ฐ ํธ๋ฆฌํฉ๋๋ค.
if case let .pizza(size) = order1 {
print("์ฃผ๋ฌธํ ํผ์ ์ฌ์ด์ฆ: \\(size)")
}
์ด์ฒ๋ผ ์ฐ๊ด๊ฐ์ case๋ง๋ค ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์ ์ฅํ ์ ์๋ ๊ธฐ๋ฅ์ ๋๋ค.
๊ฐ์ ํ์ ์์์๋ ์ฌ๋ฌ ํํ์ ์ ๋ณด๋ฅผ ํํํ ์ ์์ผ๋, ์ํฉ์ ๋ ์ง๊ด์ ์ด๊ณ ์์ ํ๊ฒ ๋ค๋ฃฐ ์ ์๊ฒ ์ฃ ?
๐ ํ๋กํ ์ฝ์ ์ฑํํ๋ ์ด๊ฑฐํ
Swift์ ์ด๊ฑฐํ๋ class๋ struct์ฒ๋ผ ํ๋กํ ์ฝ์ ์ฑํํ ์ ์์ต๋๋ค.
์ฆ, ์ด๊ฑฐํ๋ ํน์ ๊ธฐ๋ฅ์ ๋ฏธ๋ฆฌ ์ ์๋ ๊ท์น์ ๋ง์ถฐ ์ฌ์ฉํ ์ ์๋ค๋ ๋ป์ ๋๋ค.
๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ์์๊ฐ ๋ฐ๋ก CaseIterable ํ๋กํ ์ฝ์ ๋๋ค.
CaseIterable์ ์ด๊ฑฐํ์ ๋ชจ๋ case๋ฅผ ์๋์ผ๋ก ๋ชจ์์ฃผ๋ ๋ฐฐ์ด allCases๋ฅผ ์ ๊ณตํ๋ ํ๋กํ ์ฝ์ธ๋ฐ์.
์ด ํ๋กํ ์ฝ์ ์ฑํํ๋ฉด ์ด๊ฑฐํ ์์ case๋ค์ ํ๋์ฉ ์ํํ ์ ์์ต๋๋ค.
์์๋ฅผ ํ๋ฒ ์ดํด๋ด ์๋ค!
enum StudyTopic: CaseIterable {
case swift
case compose
case spring
case design
}
for topic in StudyTopic.allCases {
print(topic)
}
์ถ๋ ฅ ๊ฒฐ๊ณผ์ ์๋์ ๊ฐ์ต๋๋ค.
swift
compose
spring
design
์ด๋ ๊ฒ allCases ๋ฐฐ์ด์ ํตํด case๋ฅผ ์์๋๋ก ๊บผ๋ผ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ๋ฉ๋ด ๋ชฉ๋ก, ํญ ์ด๋ฆ, ์คํฐ๋ ์ฃผ์ ์ฒ๋ผ ์ ํด์ง ํญ๋ชฉ์ ํ ๋ฒ์ ๋ค๋ค์ผ ํ ๋ ์ ์ฉํ๊ฒ ์ธ ์ ์๊ฒ ์ฃ !
โ ๏ธ ๋จ, CaseIterable์ ์ฐ๊ด๊ฐ์ด ์๋ ์ด๊ฑฐํ์์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ฐ case์ ์ ์ฅ๋ ๋ฐ์ดํฐ(์ฐ๊ด๊ฐ)๊ฐ ๋ค๋ฅด๋ฉด, Swift๊ฐ allCases ๋ฐฐ์ด์ ์๋์ผ๋ก ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
'๐ถ๐ข๐ฆ > ๐ iOS ๊ฐ๋ ํธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [iOS / Swift] ํ ์ด๋ธ๋ทฐ์ ์ปฌ๋ ์ ๋ทฐ์ ๊ฐฑ์ ๋ฉ์๋ (0) | 2025.11.05 |
|---|---|
| [iOS / Swift] Equatable, Hashable, Comparable (0) | 2025.11.05 |
| [iOS / Swift] Optional์ด๋? (1) | 2025.10.16 |
| [iOS / Swift] ์๋ช ์ฃผ๊ธฐ(Life Cycle)๋? (0) | 2025.10.16 |
| [iOS / Swift] ์ ๊ทผ ์ ์ด์(Access Control Levels) (0) | 2025.10.16 |