[스위프트 대충보기] 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!")