์ฐธ์กฐ์ฌ์ดํธ:
The Swift Language Guide
boostcourse
enum ํค์๋๋ฅผ ์ฌ์ฉํด ์ด๊ฑฐํ์ ์ ์.
enum SomeEnumeration{
// enumeration definition goes here
}
๋ค์์ 4๊ฐ์ง ๋ฐฉํฅ์ ๊ฐ๋ CompassPoint ์ด๊ฑฐํ ์ ์ธ์ ์์.
enum CompassPoint{
case north
case south
case east
case west
}
Swift์์ ์ด๊ฑฐํ์ ์์ฑ๋ ๋ ์๋์ผ๋ก ๊ฐ case ๋ณ๋ก integer๊ฐ์ด ํ ๋น ๋์ง ์๋๋ค. (C, Object-C์ ์ฐจ์ด์ ) ์ CompassPoint๋ฅผ ๋ณด๋ฉด, ๊ฐ case๋ค์ ์์์ ์ผ๋ก 0,1,2,3๊ฐ์ ๊ฐ์ง ์๋๋ค. ๋์ ๊ฐ case๋ ๊ทธ ์์ฒด๋ก ๊ณ ์ ์ ๊ฐ์ด๋ค.
๋ํ ์ ์ธ์ ํ ์ ์ฝค๋ง(,)๋ก ๊ตฌ๋ถํด์ ํ์ค์ ์ ์ ์ ์๋ค.
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
๊ฐ ์ด๊ฑฐํ์ ์ ์ํ๋ค๋ ๋ง์ ์์ ์๋ก์ด ํ์ ์ ์ํ๋ค๋ ๋ง์ด๋ค. ๊ทธ๋ฌ๋ฏ๋ก Swift์ ๋ค๋ฅธ ํ(types)๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ด๋ฆ์ ๋๋ฌธ์๋ก ์์ํด์ผ ํ๋ค.
์๋ ์์๋ enumeration ์ธ์คํด์ค๋ฅผ ์ ์ธํ๋ ์์์ด๋ค. ํ์ ์ถ๋ก ์ ํ์ง ์๊ณ ์์ฑํ ์ ์๊ณ ํ์ ์ถ๋ก ์ ์ฌ์ฉํ์ฌ ์ ์ธํ ์ ์๋ค.
var directionToHead: CompassPoint = CompassPoint.west
//var directionToHead = CompassPoint.west
์ธ์คํด์ค๊ฐ ์ด๊ฑฐํ์ผ๋ก ํ๋ฒ ์ ์๊ฐ ๋๋ฉด ๊ทธ ํ๋ก๋ ๊ฐ์ ํ ๋นํ ๋ ํ์ ์๋ตํ ์ถ์ฝํ ๋ฌธ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค. ์๋ ์์)
directionToHead = .east
๊ฐ enumeration ๊ฐ์ Switch๋ฌธ์์ ๋งค์นญํ ์ ์๋ค. ๋งค์นญ ํ๋ ๋ฐฉ๋ฒ์ Switch๋ฌธ์ ๋น๊ต๊ฐ์ด ์์นํ๋ ์๋ฆฌ์ ์ด๊ฑฐํ ํ์ ์ ์ธ์คํด์ค๋ฅผ ์์น ์ํค๋ฉด ๋๋ค.
directionToHead = .south
switch directionToHead {
case .north:
print("Lots of planets have a north")
case .south:
print("Watch out for penguins")
case .east:
print("Where the sun rises")
case .west:
print("Where the skies are blue")
}
// Prints "Watch out for penguins"
switch๋ฌธ์ ์ด๊ฑฐํ์ ์ ์๋์ด ์๋ cases๋ค์ ๋ฐ๋์ ๋ชจ๋ ํฌํจํด์ผ ํ๋ค. ๋ง์ฝ ์์์ case .west ๊ฐ ์๋ต๋์๋ค๋ฉด case๋ฅผ ์ถ๊ฐํ๋ผ๋ ๊ฒฝ๊ณ ๋ฉ์์ง์ ํจ๊ฒ ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค. ๋ง์ฝ ๋ชจ๋ case๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์ง ์๋ค๋ฉด default case๋ฅผ ์ฌ์ฉํ์.
let somePlanet = Planet.earth
switch somePlanet {
case .earth:
print("Mostly harmless")
default:
print("Not a safe place for humans")
}
์ด์ ์น์ ์์๋ ์ด๊ฑฐํ์ด ๊ทธ ์์ฒด๋ก ์ ์๋ ๊ฐ์์ ๋ณด์ฌ์ค๋ค. ๋ํ ์์๋ ๋ณ์๋ฅผ Planet.earth๋ก ์ค์ ํ๊ณ ๋์ ์ดํ์ ์ด ๊ฐ์ ํ์ธํ ์ ์๋ค. ๊ทธ๋ฌ๋ ๋๋๋ก๋ ์ด๋ฌํ ์ผ์ด์ค๋ค์ ๊ฐ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ ํ์ ๊ฐ์ ์ ์ฅํ๋ ๊ฒ์ด ํจ์จ์ ์ผ ์ ์๋ค. ์ด๋ฅผ ์ฐ๊ด ๊ฐ(Associated Values)์ด๋ผ๊ณ ํ๋ค.
์ฆ ์ด๊ฑฐํ์ ๊ฐ case์ custom type์ ์ถ๊ฐ์ ์ธ ์ ๋ณด๋ฅผ ์ ์ฅํ ์ ์๋ค.
์๋ฅผ ๋ค์ด ์ ๋ฐ์ฝ๋์ ๊ฐ์ด 4๊ฐ์ง์ ์ซ์๋ก ์ด๋ฃจ์ด์ง ์ข ๋ฅ, 2953๊ฐ์ ๋ฌธ์๋ก ๊ตฌ์ฑ๋ QR์ฝ๋ ํํ๋ก ์ด๋ฃจ์ด์ง ๋ ์ข ๋ฅ๊ฐ ์๋ค๋ฉด ์ด ๋ฐ์ฝ๋ ๋ชจ๋๋ฅผ ์ํฉ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด case๋ค์ customํด์ผ ํ๋ฏ๋ก association values์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. ์ด ๋ฐ์ฝ๋๋ฅผ ์๋์ ๊ฐ์ด ์ ์ํ ์ ์๋ค.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
์ฐ๊ด ๊ฐ์ ์ด์ฉํ์ฌ (Int, Int, Int, Int)๋ฅผ value๋ก ๊ฐ๋ upc ๋ฐ์ฝ๋์ String์ value๋ก ๊ฐ๋ qrCode๋ฅผ ๊ฐ์ง ์ ์๋ ๊ฒ์ด๋ค.
์ด๊ฒ์ ์ค์ ๋ก Int๋ String๊ฐ์ ์ ์ฅํ๋ ๊ฒ์ด ์๋๋ผ ๋ณ์๊ฐ ์ ์ฅํ ์ ์๋ ์ ํ์ ์ ์ํ ๊ฒ์ด๋ค.
์ด enumeration์ ์ด์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด 2๊ฐ์ง ์ข ๋ฅ์ ์๋ก์ด ๋ฐ์ฝ๋๋ฅผ ๋ง๋ค ์ ์๋ค.
// Create upc barcode
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
// Create qrCode barcode
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
์ด ์์ ์์ ๋ณด๋ฉด productBarcode๋ณ์(์์)๋ .upc or .qrCode์ ์ ํ์ type์ ๋ชจ๋ ์ ์ฅํ ์ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.(๊ทธ๋ฌ๋ ๋์์๋ ์ค์ง 1๊ฐ๋ง ์ ์ฅ ๊ฐ๋ฅ)
์์ (๐Switch ๊ตฌ๋ฌธ์์ Enumeration ์ฌ์ฉ) switch๋ฌธ๊ณผ ์ ์ฌํ๋, associated value๊ฐ switch๋ฌธ์์ ์ถ์ถ๋๋ค๋ ์ ์ด ๋ค๋ฅด๋ค. switch๋ฌธ ๋ด์์ ์ด๋ ์์(let) ๋๋ ๋ณ์(var)๋ก ์ถ์ถ๋ ์ ์๋ค.
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."
์ด๋ case์์ associated values๊ฐ ์ ๋ถ ์์์ด๊ฑฐ๋ ๋ณ์์ด๋ฉด ๊ณตํต๋ ๊ฐ์ case ๋ค์ ์ ์ธํ์ฌ ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ํ ์ ์๋ค.
switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
print("UPC : \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."
associated value์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก enumeration cases๋ค์ ๋์ผํ ์ ํ์ธ ์์ ๊ฐ(raw value)์ ๊ฐ์ง๊ณ ๋ฏธ๋ฆฌ ๊ฐ์ ๊ฐ์ง ์ ์๋ค.
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}.
์ ์์์์ raw value์ chartercs๋ก ์ ์ํ์ง๋ง string, integer, float ํ์ผ๋ก๋ ์ฌ์ฉํ ์ ์๋ค. ๋จ, ๊ฐ raw value์ ์ ์ผํ ๊ฐ์ผ๋ก ์ค๋ณต๋์ด์๋ ์๋๋ค.
raw value์ associated value์ ์๋ก ๋ค๋ฅด๋ค. raw value์ ์ฝ๋์์ ์ฒ์ ์ ์๋ ๋ ๊ฐ์ ๊ฐ์ง๊ณ , ํน์ enumeration case์ raw value ํญ์ ๋์ผํ๋ค. ๊ทธ๋ฌ๋ associated values์ enumeration's cases ์ค์์ ํ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์๋ ๋ณ์๋ฅผ ๋ง๋ค ๋ ๊ฐ์ ๊ฐ์ง๋ฉฐ ์ด๋ ์์ฑ ๋๋ง๋ค ๋ค๋ฅด๋ค.
์ด๊ฑฐํ์ ๋ค๋ฃจ๋ฉด์ raw value๋ก Integer๋ String์ ์ฌ์ฉํ ์ ์๋๋ฐ, ๊ฐ case ๋ณ๋ก ๋ช ์์ (explicitly)์ผ๋ก ๊ฐ์ ํ ๋นํ ํ์๋ ์๋ค. ๋ง์ฝ ๋ช ์์ ์ผ๋ก ํ ๋นํ์ง ์์ ์, Swift์์ ์๋์ผ๋ก ๊ฐ์ ํ ๋นํ๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ฅผ ๋ค์ด raw values๋ก Integers์ ์ฌ์ฉํ๋ค๋ฉด ๊ฐ case์ value๋ ์์์ ์ผ๋ก ์ด์ ๊ฐ ๋ณด๋ค 1์ฉ ์ฆ๊ฐํ๋ค. ๋ง์ฝ ์ฒซ ๋ฒ์งธ case๊ฐ ๊ฐ์ ๊ฐ์ง๊ณ ์์ง ์๋ค๋ฉด ์๋์ผ๋ก 0 ๊ฐ์ ๊ฐ์ง๋ค.
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
์ ๊ฒฝ์ฐ๋ ์ฒซ๋ฒ์งธ case์ธ mercury์ 1์ raw value๋ก ๋ช ์์ ์ผ๋ก ํ ๋นํ๊ณ , venus๋ 2 ๊ทธ๋ฆฌ๊ณ ์ดํ ๊ฐ์ 1์ฆ๊ฐ ๋ ๊ฐ์ ์๋์ผ๋ก raw value๋ก ๊ฐ์ง๋ค. ๋ง์ฝ String์ raw ๊ฐ์ผ๋ก ์ฌ์ฉํ๋ค๋ฉด case์ name(์ด๋ฆ)์ raw value์ผ๋ก ๊ฐ์ง๊ฒ ๋๋ค.
enum CompassPoint: String {
case north, south, east, west
}
์ ๊ฒฝ์ฐ CompassPoint.south๋ ์์์ ์ผ๋ก "south"๋ฅผ raw value๋ก ๊ฐ๋๋ค.
enumeration case์ raw value์ rawValue ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ทผํ ์ ์๋ค.
let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3
let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"
๋ง์ฝ enumeration์ raw-value ํ์ ์ผ๋ก ์ ์ํ๋ค๋ฉด, enumeration์ ์๋์ผ๋ก rawValue๋ผ๊ณ ๋ถ๋ฆฌ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฐ์ง๋ initializer์ ๊ฐ์ง๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ enumeration case ๋๋ nil์ ๋ฐํํ๋ค. ์ฆ raw value์ ์ด์ฉํด ์ด๊ฑฐํ ๋ณ์๋ฅผ ์ด๊ธฐํ ํ ์ ์๋ค.
์๋ ์์๋ raw value์ด 7์ธ Uranus์ ํ์ธํ ์ ์๋ค.
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus
๋ชจ๋ Int ๊ฐ๋ค์ด ๋ง๋ planet๋ฅผ ๋ชป ์ฐพ์ ์๋ ์๋ค. initializer๋ optional enumeration case๋ฅผ ๋ฐํํ๋ค.
ํ์ ์ถ๋ก ์ ์ฌ์ฉํ์ง ์๊ณ initializer๋ฅผ ์ฌ์ฉํ๋ค๋ฉด Optional ์ธ์คํด์ค์์ ์๋์ ๊ฐ์ด ๋ช ์ํด์ฃผ์ด์ผ ํ๋ค.
let possiblePlanet: Planet? = Planet(rawValue: 7)
// error
let possiblePlanet: Planet = Planet(rawValue: 7)
raw vlaue initializer๋ failable initializer(์คํจํ ์ ์๋ ์ด๊ธฐ์)์ด๋ค. ์๋ํ๋ฉด ๋ชจ๋ raw value์ ๋ํด enmeration case์ ๋ฐํ์ด ๋ณด์ฅ๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ง์ฝ enumeration์ ์ง์ ๋ raw value๊ฐ ์๋ ๊ฐ์ผ๋ก initializer๋ฅผ ์ง์ ํ๋ฉด ๋ฐํ ๊ฐ์ nil์ด ๋๋ค.
let positionToFind = 11
if let somePlanet = Planet(rawValue: positionToFind) {
switch somePlanet {
case .earth:
print("Mostly harmless")
default:
print("Not a safe place for humans")
}
} else {
print("There isn't a planet at position \(positionToFind)")
}
// Prints "There isn't a planet at position 11"
์ฌ๊ท ์ด๊ฑฐ์(recursive enumerations)์ case ๊ฐ์ผ๋ก ๋ค๋ฅธ ์ด๊ฑฐ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ ์ด๊ฑฐํ์ด๋ค. ์ฌ๊ท ์ด๊ฑฐ์ case ์์๋ indirect ํค์๋๋ฅผ ์ฌ์ฉํ๋ค.
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
๋ง์ฝ Association value๋ฅผ ๊ฐ๋ ๋ชจ๋ ์ด๊ฑฐํ case์ indirect ํ์๋ฅผ ํ๊ณ ์ถ์ผ๋ฉด enum ํค์๋ ์์ ์ฌ์ฉํ๋ค.
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
์๋ ์์๋ (5+4) * 2 ๋ฅผ recursive enumerations์ผ๋ก ํํํ์๋ค.
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
print(product)
//Prints "18"
๋ค์์ ์์ recursive enumerations์ ๋งค๊ฐ๋ณ์๋ก ๊ฐ๋ ํจ์์ด๋ค.
func evaluate(_ expression: ArithmeticExpression) -> Int {
switch expression {
case let .number(value):
return value
case let .addition(left, right):
return evaluate(left) + evaluate(right)
case let .multiplication(left, right):
return evaluate(left) * evaluate(right)
}
}
print(evaluate(product))
// Prints "18"