[swift] 열거형Enumerations
Swift는 C의 Enumeration보다 유연하다. 각 케이스가 값을 제공할 필요가 없다. 각 케이스 별 값을 제공해야 된다면 데이터의 타입은 자유롭게 설정이 가능하다. (C는 각 케이스 별 정수 값을 반환해야 한다.)
인스턴스 메소드를 정의할 수 있고, 각 케이스 별 초기화 블럭을 정할 수 있다.
Syntax
enum [NAME] {
case [CASE_NAME]
}
enum CompassPoint {
case north
case south
case east
case west
}
// case 문 뒤에 콤마로 각 케이스를 선언할 수 있다.
enum CompassPoint {
case north, south, east, west
}
var directionToHead = CompassPoint.west
// directionToHead의 타입은 이미 알 수 있게 때문에 CompassPoint(enum의 이름)을 생략할 수 있다.
var directionToHead = .west
스위프트의 Enumeration은 C언어와 다르게 각 케이스는 기본 정수 값을 가지지 않는다.
Associated Values
각 케이스 별 다른 타입, 갯수를 정의할 수 있다. 그것을 associated values
라고 한다.
예를 들어,
바코드는 1D의 0~9까지 숫자로 제품을 구분하고,
QR 코드는 2D로 ISO 8859-1 문자로 최대 2953자까지 표현할수 있다.
UPC바코드는 4자의 숫자로 구성되고, QR 코드는 문자열(String)으로 구성된다.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
upc
케이스는 4개의 정수를 associated values, qrCode
는 String 타입의 associated value를 정의했다.
// 각 케이스를 초기화 할 때는 선언된 associated values의 타입에 맞춰 값을 넘겨주면 된다.
// upc는 Int, Int, Int, Int로 associated values가 정의되었다.
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
// qrCode는 String associated values가 정의되었다.
productBarcode = Barcode.qrCode("ABCDEFGHIJKLMNOP")
값은 최근에 변경된 값만 유지된다.
switch
문에서 각 변수에도 접근할 수 있다.
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
print("QR: \(productCode).")
}
//print "QR: ABCDEFGHIJKLMNOP."
각 케이스 별 모든 associated values를 상수(let) 혹은 변수(var)로 추출할 경우 case
키워드 다음 var 나 let 키워드를 추가하면 된다.
switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
print("QR: \(productCode).")
}
//print "QR: ABCDEFGHIJKLMNOP."
Raw Value
associated value는 각 케이스별 다른 데이터로 정의할 수 있지만, 각 케이스를 구분할 수 있는 한 타입으로 미리 정의된 값을 가질 수 있다. 이 값을 rawValue
라고 한다.
/*
enum NAME:RAW_VALUE {
case CASE_NAME
}
*/
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
ASCIIControlCharacter
는 Character
타입의 rawValue를 가진다.
tab은 “\t”
line은 “\n”
carriageReturn은 “\r”의 rawValue를 가진다.
각 rawValue는 문자, 문자열, 정수, 소수 타입으로 정의할 수 있고, 한 enum 내에서 유일하다.
associated value 와 rawValue의 특징
- rawValue는 생성되면서 정의되고, associated value는 각 케이스가 초기화 될 때 정의 된다.
- enum의 값이 변경되어도 rawValue는 변경되지 않지만, associated value는 변경 가능하다.
Implicitly Assigned Raw Values
enum은 Int, String 타입의 rawValue를 지정하지 않으면
Int는 0부터
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
Planet
의 mercury
의 rawValue를 1로 지정하면, venus
의 rawValue는 2가 되고, 다음은 3 과같이 지정된다.
enum CompassPoint: String {
case north, south, east, west
}
String은 case의 이름으로 지정된다.
Initializing from a Raw Value
rawValue를 통해 enum을 초기화 할 수 있다. 단 옵셔널로 초기화 된다.
// enum(rawValue:VALUE)
let possiblePlat = Planet(rawValue:7) // 7 == 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"
Recursive Enumerations
enumeration의 associated value를 가지는 enumeration
재귀를 표시하기 위해 case 앞에 indirect
케이스를 추가한다.
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
하나 이상의 재귀 케이스가 포함된 enum은 enum키워드 앞에 사용할 수 있다.
(5 + 4) * 2
연산을 recursive enumeration을 사용한 코드
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
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"
number
는 정수형을 반환하고, addition
, multiplication
케이스는 다시 evaluate 함수에 ArithmeticExpression 를 파리미터로 재호출 한다.
evaluate 함수는 Int(정수) 값을 반환하기 때문에 number
케이스의 값을 반환하여 다른 케이스의 연산 결과를 반환한다.
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
코드의 sum
을 evaluate(_ expression: ArithmeticExpression)
함수의 파라미터로 전달한다.
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)
}
}
먼저 switch 문에서 addition 케이스를 타게되고, addition 케이스의 association value 타입인 ArithmeticExpression을 다시 evaluate 메소드를 호출한다.
이 함수는 number 케이스의 정수형 값을 넘겨줄 때까지 재귀호출 형식으로 호출해서 최종적으로 연산된 값을 반환한다.
Author And Source
이 문제에 관하여([swift] 열거형Enumerations), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@daelous/swift-열거형Enumerations저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)