소소한개발팁
article thumbnail
반응형

Enumerations

- 열거형은 관련된 값으로 이루어진 그룹을 공통의 형으로 선언해 안정성을 보장하는 방법으로 Swift에서는 case 값이 string, character, integer, floating 값들을 사용할 수 있습니다. 또한 열거형은 1급 클래스 형이므로 계산된 프로퍼티를 제공하거나 초기화를 지정하거나, 초기 선언을 확장하여 사용할 수 있습니다.

 

 

Enumeration Syntax 

- enum 키워드를 사용하여 열거형을 정의한 예시입니다.

 

enum SomeEnumeration {
// enumeration definition goes here
}

 

- 아래는 네 가지의 방향을 갖는 CompassPoint 열거형 선언의 예시입니다.

 

enum CompassPoint {
 case north
 case south
 case east
 case west
}

 

- Swift에서는 열거형은 생성될 때 각 case별로 기본 integer값을 할당하지 않습니다. 아래는 ( , ) 를 사용하여 한 줄에 적은 예시입니다.

 

enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

 

- 각 열거형 정의는 완전 새로운 형으로 정의를 합니다. 또한 생성 시 대문자로 시작해야 합니다. 아래는 생성한 enum을 변수 값으로 지정하는 예시입니다.

 

var directionToHead = CompassPoint.west

 

- 이렇게 변수에 한번 값이 지정됐을 경우 축약하여 변경된 값을 같은 enum 형으로 변경할 수 있습니다. 아래의 예시와 같습니다.

 

directionToHead = .east

 

 

Matching Enumeration Values with a Switch Statement 

- 열거형 값을 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문은 반드시 열거형의 모든 경우를 완전히 포함해야 합니다. 만약 위에서 case .westcase. west가 생략되었다면 코드는 컴파일되지 않습니다. 만약 열거형의 모든 cases의 처리를 기술하는 게 적당하지 않다면 아래의 예시와 같이 기본 case를 제공함으로써 처리되지 않는 case를 피할 수 있습니다.

 

let somePlanet = Planet.earth
   switch somePlanet {
     case .earth:
       print("Mostly harmless")
     default:
       print("Not a safe place for humans")
   }
// Prints "Mostly harmless"
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

 

 

Associated Values 

- 열거형의 각 case에 custom type의 추가적인 정보를 저장할 수 있습니다.

바코드
QR코드

- 예를 들어 바코드가 위와 같이 4가지 구분으로 이루어진 숫자로 이루어진 종류가 있거나, 2,953개의 문자로 구성된 QR코드 형태로 이루어진 두 가지 종류가 있다면 이 바코드를 아래와 같은 열거형으로 정의할 수 있습니다.

 

enum Barcode {
  case upc(Int, Int, Int, Int)
  case qrCode(String)
}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

 

- switch case문에서 사용할 때 상수 혹은 변수로도 선언할 수 있습니다.

 

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 안의 관련 값이 전부 상수이거나 변수이면 공통된 값을 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."

 

 

Raw Values 

- case에 raw 값을 지정할 수 있습니다.

 

enum ASCIIControlCharacter: Character {
 case tab = "\t"
 case lineFeed = "\n"
 case carriageReturn = "\r"
}

 

- 위 예제에서는 Character형의 raw값으로 정의했지만, String, Character, Integer,Float등의 형을 사용할 수도 있습니다. 단, 각 raw값은 열거형 선언에서 유일한 값으로 중복되어서는 안 됩니다.

 

 

Implicitly Assigned Raw Values 

- 열거형을 다루면서 raw값으로 Integer나 String 값을 사용할 수 있는데, 각 case별로 명시적으로 raw값을 할당할 필요는 없습니다.

 

enum Planet: Int {
  case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

 

- 위 경우는 mercury에 1을 raw 값으로 명시적으로 할당했고 venus는 암시적으로 2 그리고 이후 값은 1 증가된 값을 자동으로 raw값으로 갖게 됩니다. 만약 String을 raw값으로 사용한다면 case텍스트가 raw값으로 자동으로 raw값으로 할당됩니다.

 

enum CompassPoint: String {
  case north, south, east, west
}

 

- 위 경우 CompassPoint.south는 암시적으로 "south"를 raw값으로 갖습니다. 또한 아래의 예시와 같이 raw값은 rawValue 프로퍼티를 사용해 접근할 수 있습니다.

 

let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

 

 

Initializing from a Raw Value 

- raw값을 이용해 열거형 변수를 초기화할 수 있습니다. 아래 예제는 raw값 7을 갖는 값을 열거형 변수의 초기 값으로 지정합니다.

 

let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus

 

- 만약 열거형에 지정된 raw값이 없는 값으로 초기자를 지정하면 그 값은 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는 앞에 indirect 키워드를 붙여 표시합니다.

 

enum ArithmeticExpression {
  case number(Int)
  indirect case addition(ArithmeticExpression, ArithmeticExpression)
  indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

 

- 만약 관계 값을 갖는 모든 열거형 case에 indirect표시를 하고 싶으면 enum 키워드 앞에 indirect 표시를 하면 됩니다.

 

indirect enum ArithmeticExpression {
 case number(Int)
 case addition(ArithmeticExpression, ArithmeticExpression)
 case multiplication(ArithmeticExpression, ArithmeticExpression)
}

 

- 아래 예제는 ( 5 + 4 ) * 2를 재귀 열거자로 표현한 것입니다.

 

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"

 

 

내용은 https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html를 보면서 작성하였고 원문으로 작성된 내용을 옮기다 보니 이상한 부분이 있을 수 있습니다. 자세한 내용은 위의 링크를 확인해주시기 바랍니다.

반응형
profile

소소한개발팁

@개발자 뱅

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!