Swift 에서는 while 문과 for 문 두 가지의 loop 문이 들어갑니다. 그런데 여기서 주의해야 할 점은 다른 언어와는 다르게 조건문에 괄호 “()” 를 넣지 않는다 는 점과 많은 다른 언어에서 자주 사용하는 for(int i=0 ; i<10 ; i++) 과 같은 syntax 를 사용하지 않는다 는 것입니다. 이 두 가지를 유의해서 사용하도록 해야 합니다.

while

while 문은 다른 언어들과 동일하게 사용됩니다. while 문의 조건이 false 가 될때까지 반복하고 false 가 되면 빠져나옵니다. 조금 특이한 점이 있다면 do-while 문이 아니라 repeat-while 문으로 사용한다는 것입니다.

일반 while loop

초기화가 존재하지 않으며 조건식만으로 loop 를 돌리다가 조건이 false 가 되면 while 문을 빠져나옵니다.

var i=0
while i < 10 {
  print(i)
  i += 1
}

repeat-while loop

다른 언어에서 자주 사용되는 do-while 문과 동일한 방식으로 사용됩니다. 다만 do 를 repeat 으로 사용할 뿐입니다. 이 loop 는 repeat 안의 문이 한번은 반드시 실행되고 while 문을 체크해서 false 가 될때까지 repeat 을 계속 실행시킵니다. 일반 while loop 와의 차이점은 단순히 repeat 문을 한번은 반드시 실행한다는 점입니다.

var i = 10
repeat {
  print(i)
  i++
} while i< 10

// 10 이 한번 찍히고 끝나게 됩니다.

for-in

앞에서도 이야기 했지만 swift 에서의 for loop 는 for-in loop 만을 제공합니다. 하지만 range operator 를 이용하면 이와 비슷하게 사용할 수 있으니 걱정하지 않으셔도 될 것 같습니다.

배열 과 for loop

배열을 for in 문에 사용하면 배열안의 value 를 하나씩 리턴해줍니다.

let names = ["Anna", "Alex", "Brian", "Jack"]
for i in names {
  print("Person \(i + 1) is called \(names[i])")
}

뒤에서 이야기하겠지만 예전과 비슷한 for(i=0 ; i<10 ; i++) 과 비슷한 syntax 로 싶다면 count 메서드와 range operator 를 이용하여 배열에서 index를 이용해 값을 각각 꺼내서 사용할 수도 있습니다.

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
  print("Person \(i + 1) is called \(names[i])")
}

dictionary 와 for loop

dictionary 를 사용하면 key 와 value 를 리턴해줍니다. 이를 각각 변수로 받아서 loop 문 내에서 이용할 수 있습니다. 참고로 dictionary 는 order 된 자료구조가 아니므로 [index] 로는 객체를 접근할 수 없다는 것을 주의해야 합니다.

let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
    print("\(animalName)s have \(legCount) legs")
}
// ants have 6 legs
// spiders have 8 legs
// cats have 4 legs

Range Operator

사실 swift 에서는 이 Range Operator 를 이용하면 for-in 문에서 많은 기능을 수행할 수 있습니다. Closed Range Operator 의 경우에는 아래와 같이 사용할 수 있습니다.

// 1~ 5 까지 반복
for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}

참고로 만약 range 의 변수를 사용하지 않고 단순히 반복하기 위해서만 사용할 경우 _(underscore) 를 사용하는 것이 관례입니다.

// 순수히 반복, 변수를 이용
let power = 10
var answer = 1
for _ in 1...power {
    answer *= 2
}

위에서 이야기한 Half-Open Range Operator 를 이용할 수도 있습니다. 이는 마지막 값이 들어가지 않기 때문에 시간이나 배열에서 count 와 함께 자주 쓰일 것 같다는 생각이 많이 듭니다.

let minutes = 60
for tickMark in 0..<minutes {
    // render the tick mark each minute (60 times)
}

stride 이용하기 (특정 범위씩 건너 뛰면서 사용)

먼저 stride(from:to:by) 와 같은 형식으로 사용할 수 있습니다. 이 뜻은 from 부터 to 까지 by 만큼 건너뛰면서 값을 가져오겠다는 이야기입니다. 아래 예를 보면 이해가 될 것으로 생각됩니다. 주의할 점은 가운데 to 로 되어 있는 경우는 Half-Open Range Operator 로 사용되기 때문에 마지막에 값이 있다면 가져오지 않는다는 점입니다.

let minuteInterval = 5
for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
    // render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55)
    // 60 은 X
}

여기서 stride(from:through:by) 와 같이 가운데 인자를 through 로 받는 다면 이는 Closed Range Operator 로 사용하겠다는 뜻입니다.

let hours = 12
let hourInterval = 3
for tickMark in stride(from: 3, through: hours, by: hourInterval) {
    // render the tick mark every 3 hours (3, 6, 9, 12)
}