안녕하세요. 엘림입니다🙇🏻♀️
Swift 공식 문서 정독하기 8편입니다!
제 스타일대로 정리했으니 추가적으로 더 필요한 정보는
공식문서 링크를 눌러 확인해주세용!
좀 더 편하게 보기위해 한국어로 번역된 사이트를 함께 확인했습니다!ㅎㅎ
자, 그럼 시작해볼까요
이 글은 공부하면서 작성한 글이기 때문에 잘못된 정보가 있을 수 있습니다.🥺
금방 잊어버릴... 미래의 저에게 다시 알려주기 위한 글이다보니
혹시라도 틀린 부분이 있다면, 댓글로 친절하게 알려주시길 부탁드립니다.🙏
열거형은 관련된 값으로 이루어진 그룹을 하나의 타입으로 선언해 안전성(type-safety)을 보장하는 방법입니다. 스위프트에서는 case값으로 string, character, integer, floting 등 을 사용할 수 있습니다. 열거형은 1급 클래스 형(first-class types)이어서 연산 프로퍼티(computed properties)를 제공하거나 초기화를 지정하거나, 초기 선언을 확장해 사용할 수 있습니다.
enum CompassPoint {
case north
case south
case east
case west
}
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
Swift에서 열거형은 생성될 때 각 case 별로 기본 integer값을 할당하지 않습니다
var directionToHead = CompassPoint.west
directionToHead = .east
directionToHead의 형은 초기화 될 때 타입추론이 돼서 CompassPoint형을 갖게 됩니다. directionToHead의 형이 CompassPoint로 한번 정의되면 다음에 값을 할당할 때 형을 생략한 점 문법(dot syntax)을 이용해 값을 할당하는 축약형 문법을 사용할 수 있습니다.
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"
let somePlanet = Planet.earth
switch somePlanet {
case .earth:
print("Mostly harmless")
default:
print("Not a safe place for humans")
}
switch문은 반드시 열거형의 모든 경우(cases)를 완전히 포함해야 합니다. 만약 case가 생략되었다면 코드는 컴파일 되지 않습니다. 만약 열거형의 모든 cases의 처리를 기술하는게 적당하지 않다면 기본(default) case를 제공함으로써 처리되지 않는 case를 피할 수 있습니다.
enum Beverage: CaseIterable {
case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases.count
print("\(numberOfChoices) beverages available")
// Prints "3 beverages available"
for beverage in Beverage.allCases {
print(beverage)
}
// coffee
// tea
// juice
CaseIterable을 채택한 enum은 allCases을 다른 컬렉션처럼 사용할 수 있습니다.
열거형의 각 case에 custom type의 추가적인 정보를 저장할 수 있습니다.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
예를 들어 바코드가 위와 같이 4가지 구분으로 이루어진 숫자로 이루어진 종류가 있거나, 2,953개의 문자로 구성된 QR코드 형태로 이루어진 두 가지 종류가 있다면 이 바코드를 아래와 같은 열거형으로 정의할 수 있습니다.
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."
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."
case 안의 관련 값이 전부 상수이거나 변수이면 공통된 값을 case 뒤에 선언해서 보다 간결하게 기술할 수 있습니다. 공통된 let을 앞으로 빼내 간결하게 기술도 가능합니다.
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
각 raw값은 열거형 선언에서 유일한 값으로 중복되어서는 안됩니다.
열거형을 다루면서 raw값으로 Integer나 String 값을 사용할 수 있는데, 각 case별로 명시적으로 raw값을 할당할 필요는 없습니다. 만약 raw값을 할당하지 않으면 Swift에서 자동으로 값을 할당해 줍니다.
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
enum CompassPoint: String {
case north, south, east, west
}
let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3
let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"
mercury에 1을 raw 값으로 명시적으로 할당했고 venus는 암시적으로 2 그리고 이후 값은 1증가 된 값을 자동으로 raw값으로 갖게 됩니다. 만약 String을 raw값으로 사용한다면 case텍스트가 raw값으로 자동으로 raw값으로 할당됩니다.
또한, CompassPoint.south는 암시적으로 "south"를 raw값으로 갖습니다.
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus
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"
raw 값 초기자는 모든 raw값에 대해 열거형 case를 반환이 보장되지 않으므로 실패할 수 있는 초기자(failable initializer)입니다.
만약 열거형에 지정된 raw값이 없는 값으로 초기자를 지정하면 그 값은 nil이 됩니다.
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
재귀 열거자는 다른 열거 인스턴스를 관계 값으로 갖는 열거형입니다. 재귀 열거자 case는 앞에 indirect키워드를 붙여 표시합니다.
만약 관계 값을 갖는 모든 열거형 case에 indirect표시를 하고 싶으면 enum키워드 앞에 indirect표시를 하면 됩니다.
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
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"
오늘은 스위프트 공식문서에서 Enumerations 읽어보았습니다~
다음에는 Structures and Classes를 읽어보도록 하겠습니다!
감사합니다🙇🏻♀️