Skip to content

Latest commit

 

History

History
executable file
·
121 lines (95 loc) · 4.24 KB

[스위프트 대충보기] 7. 열거형(enumeration) (1).md

File metadata and controls

executable file
·
121 lines (95 loc) · 4.24 KB
Error in user YAML: (<unknown>): did not find expected key while parsing a block mapping at line 1 column 1
---
layout: post
title: [스위프트 대충보기] 7. 열거형(enumeration)
tags: 스위프트, swift, 배열, 딕셔너리, 맵, array, dictionary, map
---

[스위프트 대충보기] 7. 열거형(enumeration)

열거형 기초

  • 열거형: 기본적으로는 식별자들을 한 타입으로 사용하고 싶을 때 이넘 타입을 선언

      enum CompassPoint {
      	case North
          case South
          case East
          case West
      }
    
  • 여러줄로도, 한줄로도 쓸 수 있음

      enum CompassPoint {
      	case North, South, East, West
      }
    
  • 값은 이름.케이스이름으로 사용. 타입은 이름이 타입이 됨

      var direction = CompassPoint.North // direction은 CompassPoint타입
    
  • 변수 타입이 정해지면, 대입시 타입이 분명하기 때문에 굳이 열거형 이름을 적을 필요가 없음. 다만 열거값임을 표현하기 위해 .는 앞에 찍어줌

      direction = .East
    
  • switch 문으로 매치 가능

      let directionToHead2:CompassPoint = .North
      switch directionToHead2 {
          case .North:
              println("Lots of planets have a north")
          case .South:
              println("Watch out for penguins")
          case .East:
              println("Where the sun rises")
          case .West:
              println("Where the skies are blue")
      }
    
  • 이넘의 case에 값을 연결할수 있음(연관값, associated value라 부름)

      enum Barcode {
          case UPCA(Int, Int, Int)
          case QRCode(String)
      }
      var productCode = Barcode.UPCA(8, 85909_51226,3)
    
  • switch로 매치시 case 이름을 사용해 각 성분을 분리해 낼 수 있음

      switch productBarcode {
      	case .UPCA(let numberSystem, let identifier, let check):
          	println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
      	case .QRCode(let productCode):
          	println("QR code with value of \(productCode).")
      }
    
  • 열거형 뒤에 :로 타입을 지정하고, 각 case 식별자마다 기본값(로우(raw) 값)을 지정 가능. 로우값으로 지정가능한 타입은 문자열, 문자, 정수 또는 부동소수 타입 뿐임. 연관값은 case 식별자마다 다 타입을 다르게 부여할 수 있고, 어떤 타입이건 가능하지만, 로우값은 그렇지 않음에 유의할 것.

      enum ASCIIControlCharacter: Character {
          case Tab = "\t"
          case LineFeed = "\n"
          case CarriageReturn = "\r"
      }
    
  • 로우값은 toRaw 메서드로 얻을 수 있고, 거꾸로 fromRow 메서드를 사용 하면 로우값에서 열거형 case 식별자를 얻을 수 있음. fromRow는 열거형? 타입(옵션타입)임

      let ascii = ASCIIControlCharacter.fromRaw("\r") // ASCIIControlCharacter? 타입
    
  • 심심풀이: 이상한 expression 계산기

      // 그냥 case안에 함수도 묶을 수 있나 보기 위해...
      enum Operator {
      	case ADD((Int,Int)->Int)
          case SUB((Int,Int)->Int)
          case MUL((Int,Int)->Int)
          case DIV((Int,Int)->Int)
      }
      
      enum Expr {
          case BINOP(Operator, Expr, Expr)
          case NUMBER(Int)
      }
      
      // 연산자를 잘 표현할 방법이...
      let ADDOP = Operator.ADD(+)
      let SUBOP = Operator.SUB(-)
      let MULOP = Operator.MUL(*)
      let DIVOP = Operator.DIV(/)
      
      func calc(e:Expr)->Int {
      	switch(e) {
          	case BINOP(op, e1, e2):
              	switch(op) {
                  	case ADD(f):
                      	return f(calc(e1), calc(e2))
                      case SUB(f):
                      	return f(calc(e1), calc(e2))
                      case MUL(f):
                      	return f(calc(e1), calc(e2))
                      case DIV(f):
                      	return f(calc(e1), calc(e2))
                  }
              case NUMBER(v):
              	return v
          }
      }
      
      // (1*3) + (6/2)
      let testExp = Expr.BINOP(ADDOP,
      			Expr.BINOP(MULOP,.Number(1),.NUMBER(3)),
                  Expr.BINOP(DIVOP,.Number(6),.NUMBER(2))
      		)
      
      println("(1*3) + (6/2) = \(calc(testExp)))