티스토리 뷰
eunmeration은 관련있는 값들을 그룹지어 주는 타입이고 코드를 타입적으로 안전하게 값들을 다룰 수 있도록 돕습니다. 만약 당신이 C에 익숙하다면 C의 enumeration은 이름과 관련된 정수 값을 세트로 가지고 있다는 것을 알고 있을 것입니다. swift의 enumeration은 좀 더 유연성 있게 되었습니다. 그리고 enumeration의 어떤 case도 값을 제공할 필요가 없습니다. 만약 raw value 라고 불리는 한 값이 각각의 enumeration case 값에 제공된다면, 그 값은 string, character 또는 어떤 정수, 실수값이든 가능합니다.
swift의 enumeration은 그 자체로 first-class 타입입니다.( 정확히 무슨 의미인지 모르겠는데 대강 클래스 타입이다 이런 소리 같음) 전통적으로 클래스에서만 지원되는 연산 프로퍼티, 인스턴스 메소드 등을 사용가능합니다. enumeration(이하 열거형)도 초기값을 주는 생성자를 정의 할 수 있고 구현을 확장시켜 기능을 추가할 수 있고 프로토콜을 통해 표준 기능을 제공할 수 있습니다.
열거형의 기본 문법
enum CompassPoint {
case north
case south
case east
case west
}
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
var directionToHead = CompassPoint.west
directionToHead = .east
// 축약형. directionToHead가 CompassPoint 타입이란 걸 미리 알고 있다면 사용가능
축약형은 굉장히 많이 쓰인다.
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")
}
Iterating over Enumeration Cases
몇몇 열거형은 열거형의 케이스들의 모든 콜렉션을 가지는 것이 유용하다. :CaseIterable을 이름뒤에 붙여주면 스위프트가 모든 콜렉션을 allCases 프로퍼티에 담아준다.
enum Beverage: CaseIterable {
case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases.count
print("\(numberOfChoices) beverages available")
--------------------------------------------------
for beverage in Beverage.allCases {
print(beverage)
}
// coffee
// tea
// juice
Associated Values
다른 언어에서 unions나 variants의 기능과 유사하다고 하는데 난 처음 들어본다; 튜플의 좀 더 업그레이드 버전 느낌인데 연관되어 있는 값을 묶어 저장시켜주는 기능. 예제는 바코드의 일반적인 라인 형태와 qr코드를 동시에 저장가능한 열거형이다,.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
변수 혹은 상수는 이런식으로 값을 받으면 해당 열거형 타입으로 저장이 되며 점을 붙여 해당 케이스에 접근 가능하다.
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).")
}
associated value를 통채로 저장하고 싶으면 case 뒤에 var 또는 let을 붙이면 된다.
Raw Values
default value로 이미 잘 알려진 raw value는 case 값 마다 미리 값을 지정해줄 수 있다.
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
이름 뒤에 Character 타입을 넣어주고 초기값을 넣어주는 것처럼 케이스마다 값을 넣어주면 된다. 앞서 언급했듯이 어떤 정수,상수,문자,문자열도 앞서 넣어준 타입과 일치하면 상관없이 넣어줄 수 있다.
Implicitly Assigned Raw Values
암시적으로 raw value를 넣어주는 기능.
정수의 경우 전 케이스보다 1 더해서 넣어준다. 만약 첫번째 케이스 값에도 아무것도 안넣어주면 첫번째 값은 0이 된다.
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
문자열의 경우. 케이스의 이름이 그대로 들어간다.
Initializing from a Raw Value
만약에 raw value 를 넣어준 열거형의 경우 파라미터로 rawValue 값을 받는 생성자가 하나 생기는데 맞는 값을 넣어주면 케이스가 반환되고 없는 rawValue를 넣어주면 nil이 반환된다. 당연히 nil이 반환될 가능성이 있으므로 리턴타입은 어쨌거나 옵셔널.
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus
Recursive Enumerations
이름에 재귀가 들어가듯 가지고 있는 case 값을 associated value처럼 활용하면서 case를 만든다. 앞에 indirect를 붙임으로서 만들 수 있다.
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)
}
//모든 열거형의 케이스가 associated value를 가지고 있는 enumeration이라고 맨앞에 붙임으로서 알려줄 수 있음
'Swift Language Guide' 카테고리의 다른 글
8. 프로퍼티 (0) | 2020.11.03 |
---|---|
7. Structures and Classes (0) | 2020.11.02 |
5. Closures (0) | 2020.10.31 |
4. Functions (0) | 2020.10.29 |
3. Control Flow (0) | 2020.10.28 |