Skip to content

Latest commit

 

History

History
executable file
·
143 lines (107 loc) · 5.8 KB

스위프트-4.흐름제어.md

File metadata and controls

executable file
·
143 lines (107 loc) · 5.8 KB

[스위프트 대충보기] 4. 제어 흐름? 흐름 제어?(control flow)

  • C 비슷한 흐름제어 제공

  • For 루프

  • for-in 루프: 컬렉션에 대해 이터레이션

          for index in 1...5 {
              println("\(index) times 5 is \(index * 5)")
          } // 여기서 index는 {} 안에서는 상수임
    
  • range사용시 인덱스가 필요 없으면 _로 무시 가능

          // 간단 피보나치 수열 출력
          var sum1=1, sum2=0
    
          for _ in 1...10 { 
            sum1 += sum2
            sum2 = sum1
            println("\(sum1)")
          }
    
  • 딕셔너리, 배열, 문자열에 대한 이터레이션 : 컬렉션 부분 참조

  • for-조건-증분 루프: C의 for루프 (근데 왜 for-초기화-조건-증분이 아니고 for-조건-루프인거야?)

          for var index = 0; index < 3; ++index {
              println("index is \(index)")
          }
    

(더이상의 설명이 필요한지?)

  • for 초기화; 조건; 증분 { 본체 } 루프는 다음 while 루프의 축약형

          초기화
          while 조건 {
            본체
            증분
          }
    
  • while 루프 - 더이상의 설명은 생략한다

  • do while 루프 - 더이상의 설명은 생략한다

  • if 조건 { 문장들 } [ else { 문장들 } ] - 더이상의 설명은 생략한다

  • switch 대상 { case 값: 문장 default: 문장 }

  • 반드시 모든 스위치의 case는 모든 경우를 커버해야 함!(exhaustive). exhaustive하지 않으면 무조건 default를 지정해야함(!).

  • case 'a': 한 다음에 아무 문장도 안쓸 수는 없다(!). 컴파일 오류가 난다. 매치는 하되 실행할 것이 없으면, break를 바로 넣어서 흐름을 다음으로 넘겨라.

  • 기본적으로는 fallthrough(case문이 자동으로 다음번 case문으로 진행하는 것)가 안된다. 따라서, 중간에 더 빨리 빠져나오고 싶은 경우이거나, 아무 일도 안하는 case가 아니면 굳이 break를 쓸 필요가 없다.

  • case문에서 조건부분이 단순한 상수 말고 ,로 구분해 여러 상수들을 나열해 매치하거나, 복잡한 패턴도 기술할 수 있다.

  • 범위 매칭: case 0..9: ... 또는 case 10...20: ...

  • 튜플매칭: 튜플과 매칭 가능, 튜플 각 원소를 범위와 매치 가능

          let somePoint = (1, 1)
          switch somePoint {
          case (0, 0):
              println("(0, 0) is at the origin")
          case (_, 0):
              println("(\(somePoint.0), 0) is on the x-axis")
          case (0, _):
              println("(0, \(somePoint.1)) is on the y-axis")
          case (-2...2, -2...2):
              println("(\(somePoint.0), \(somePoint.1)) is inside the box")
          default:
              println("(\(somePoint.0), \(somePoint.1)) is outside of the box")
          }
    
  • 값 바인딩: case의 패턴 안에서 let이나 var로 변수/상수 바인딩 가능

          let anotherPoint = (2, 0)
          switch anotherPoint {
          case (let x, 0):
              println("on the x-axis with an x value of \(x)")
          case (0, let y):
              println("on the y-axis with a y value of \(y)")
          case let (x, y):
              println("somewhere else at (\(x), \(y))")
          }
    
  • 조건 사용: case의 패턴 안에 where을 사용해 조건 체크 가능

          let yetAnotherPoint = (1, -1)
          switch yetAnotherPoint {
          case let (x, y) where x == y:
              println("(\(x), \(y)) is on the line x == y")
          case let (x, y) where x == -y:
              println("(\(x), \(y)) is on the line x == -y")
          case let (x, y):
              println("(\(x), \(y)) is just some arbitrary point")
          }
    
  • 제어 이동(control transfer) 명령: continue, break, fallthrough, (return은 함수부분에서 설명)

  • continue: 설명 생략

  • break: 설명 생략

  • fallthrough: case에서 다음 case로 계속 실행을 이어나가고 싶을 때 이를 명시함. (주의: fallthrough로 제어가 넘어갈때는 다음번 case문을 체크하지 않고 그 안으로 실행이 넘어간다. 즉, C switch/case에서의 동작과 같다)

          let integerToDescribe = 5
          var description = "The number \(integerToDescribe) is"
          switch integerToDescribe {
          case 2, 3, 5, 7, 11, 13, 17, 19:
              description += " a prime number, and also"
              fallthrough
          default:
              description += " an integer."
          }
          println(description)
    
  • 라벨 붙은 문장: 문장 앞에 라벨을 붙이고, continue, break에서 라벨을 지정해 그리로 이동 가능

              let finalSquare = 25
              var board = Int[](count: finalSquare + 1, repeatedValue: 0)
              board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
              board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
              var square = 0
              var diceRoll = 0
    
              gameLoop: while square != finalSquare {
                  if ++diceRoll == 7 { diceRoll = 1 }
                  switch square + diceRoll {
                  case finalSquare:
                      // diceRoll will move us to the final square, so the game is over
                      break gameLoop
                  case let newSquare where newSquare > finalSquare:
                      // diceRoll will move us beyond the final square, so roll again
                      continue gameLoop
                  default:
                      // this is a valid move, so find out its effect
                      square += diceRoll
                      square += board[square]
                  }
              }
              println("Game over!")