
Go 반복문, 왜 지금 바로 마스터해야 할까요?
코드를 작성하다 보면 똑같은 작업을 수십, 수백 번 반복해야 하는 순간이 찾아와요. 단순히 숫자를 1부터 100까지 출력하는 일부터, 복잡한 데이터 목록을 하나씩 검사하는 일까지 말이에요. 이때 Go 반복문 치트시트를 알고 있다면 막막했던 코딩 시간이 훨씬 즐거워질 수 있어요.
많은 초보 개발자가 Go 언어를 처음 접할 때 당황하는 지점이 바로 여기예요. 다른 언어들처럼 while 문이나 do-while 문이 따로 존재하지 않거든요. “왜 Go에는 반복문이 딱 하나뿐이지?”라는 의문이 든다면, 여러분은 이미 Go의 철학에 가까워진 거예요. Go는 단순함을 지향하며, 모든 반복 로직을 단 하나의 키워드인 for로 해결하도록 설계되었어요.
반복문을 제대로 다루지 못하면 무한 루프에 빠져 프로그램이 멈추거나, 리스트의 범위를 벗어나 에러를 뿜어내는 코드를 만들게 돼요. 이런 실수는 단순한 오타가 아니라 반복문의 동작 원리를 정확히 이해하지 못했기 때문에 발생해요. 오늘 이 글을 통해 반복문의 기본 문법부터 실전에서 바로 써먹는 고급 패턴까지 모두 가져가세요.
이 글을 끝까지 읽고 나면 여러분은 다음과 같은 능력을 갖게 돼요.
- 상황에 맞는 최적의 for 문 형식을 선택할 수 있어요.
- 리스트나 맵 데이터를 효율적으로 순회하는 방법을 익혀요.
- 실무에서 자주 발생하는 반복문 에러를 스스로 해결할 수 있어요.
반복문 시작 전 꼭 알아야 할 핵심 개념
본격적으로 코드를 치기 전에, Go의 반복문이 어떤 구조로 이루어져 있는지 머릿속에 그려두는 과정이 필요해요. Go의 반복문은 유연성이 매우 뛰어나서, 하나의 키워드로 여러 가지 형태를 만들어낼 수 있다는 점이 가장 큰 특징이에요.
먼저 우리가 사용할 도구들의 성격을 파악해 봐요. Go의 반복문은 크게 세 가지 구성 요소로 나눌 수 있어요. 첫 번째는 반복을 시작할 때 값을 설정하는 초기화 문(initialization), 두 번째는 반복을 계속할지 결정하는 조건식(condition), 마지막으로 매 반복이 끝날 때마다 실행되는 후속 문(post statement)이에요. 이 세 가지를 어떻게 조합하느냐에 따라 코드의 모습이 완전히 달라져요.
Go에는 while 문이 따로 없어요. 대신 condition만 적은 for 문을 사용하면 C언어나 자바의 while 문과 똑같은 역할을 수행해요.
어떤 형태의 반복문을 써야 할지 고민될 때는 아래 표를 참고해서 결정해 보세요. 각 상황에 맞는 최적의 선택 기준을 정리해 두었어요.
| 반복문 유형 | 주요 용도 | 판단 기준 |
|---|---|---|
| 표준형 for | 횟수가 정해진 반복 | 시작값, 조건, 증감식이 명확할 때 |
| 조건식 for | 특정 조건이 유지될 때까지 | while 문처럼 조건만 중요할 때 |
| 무한 for | 중단 조건이 나타날 때까지 | 내부에서 break를 사용해 탈출할 때 |
| range for | 컬렉션(슬라이스, 맵 등) 순회 | 데이터의 처음부터 끝까지 훑어야 할 때 |
단순히 코드를 따라 쓰는 것보다, 지금 내 상황에서 어떤 반복문이 가장 가독성이 좋은가를 고민하는 태도가 중요해요. 가독성이 좋은 코드는 나중에 여러분이 다시 보거나 동료가 볼 때 훨씬 이해하기 쉽기 때문이에요. 이제 준비가 되었다면 실제 코드가 어떻게 돌아가는지 단계별로 살펴볼까요?
실전에서 바로 쓰는 Go 반복문 활용법
이제 본격적으로 코드를 작성해 볼 시간이에요. 이론만으로는 부족하죠. 실제 어떤 패턴이 실무에서 가장 많이 쓰이는지, 단계별로 구체적인 예제와 함께 확인해 봐요.
STEP 1. 가장 기본이 되는 표준형 for 문
가장 전형적인 형태로, C 언어나 Java를 경험해 본 분들이라면 매우 익숙한 구조예요. 세미콜론(;)을 기준으로 세 영역을 구분해요. 이 방식은 반복할 횟수를 정확히 제어해야 할 때 아주 유용해요.
// 1부터 5까지 출력하는 표준형 for 문
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
여기서 i := 1은 시작점, i <= 5는 언제까지 달릴 것인지에 대한 약속, 그리고 i++는 한 걸음씩 나아가는 방식이에요. 만약 i++를 빼먹는다면 어떻게 될까요? 조건이 계속 참이 되어 프로그램이 영원히 멈추지 않는 무한 루프에 빠지게 돼요. 항상 증감식이 제대로 포함되었는지 확인하는 습관을 가져야 해요.
STEP 2. 데이터를 훑을 때 필수인 range 활용법
Go 개발자들이 가장 사랑하는 방식이에요. 슬라이스(Slice)나 맵(Map) 같은 데이터 묶음을 다룰 때, 인덱스 번호를 일일이 계산할 필요가 없어서 정말 편해요. range 키워드는 데이터의 인덱스와 실제 값을 동시에 던져줘요.
names := []string{"철수", "영희", "민수"}
// 인덱스(i)와 값(name)을 모두 사용하기
for i, name := range names {
fmt.Printf("%d번째 손님: %s\n", i, name)
}
// 인덱스가 필요 없다면 언더바(_)를 사용해요
for _, name := range names {
fmt.Println("이름:", name)
}
여기서 중요한 팁 하나! 만약 인덱스 번호가 필요 없는데 굳이 변수를 만들어 두면, Go 컴파일러가 "사용하지 않는 변수가 있다"며 에러를 낼 수 있어요. 그럴 때는 반드시 언더바(_)를 사용해서 해당 값을 무시하겠다고 명시해야 해요. 이것이 Go답게 코딩하는 방법이에요.
STEP 3. 흐름을 제어하는 break와 continue
반복문을 돌리다가 중간에 멈추거나, 이번 차례만 건너뛰고 싶을 때가 있죠? 이때 사용하는 것이 break와 continue예요. 이 두 키워드만 잘 써도 로직이 훨씬 정교해져요.
- break: 반복문을 즉시 종료하고 밖으로 탈출해요.
- continue: 현재 진행 중인 단계를 건너뛰고 다음 반복으로 바로 넘어가요.
// 1부터 10까지 숫자 중 3의 배수만 출력하고, 7이 나오면 종료하기
for i := 1; i <= 10; i++ {
if i % 3 == 0 {
fmt.Println(i, "는 3의 배수예요!")
continue // 3의 배수면 아래 코드를 무시하고 다음 숫자로 넘어가요
}
if i == 7 {
fmt.Println("7을 만났으니 멈출게요.")
break // 반복문을 즉시 끝내요
}
fmt.Println(i)
}
STEP 4. 조건만으로 작동하는 while 스타일 루프
Go에는 별도의 while 문이 없지만, for 문을 활용해 똑같은 기능을 구현할 수 있어요. 특정 조건이 참(true)인 동안 계속 무언가를 수행해야 할 때 사용해요. 예를 들어, 네트워크 연결이 성공할 때까지 계속 시도하는 로직을 짤 때 아주 적합해요.
count := 0
// count가 5보다 작을 때까지만 반복해요
for count < 5 {
fmt.Println("현재 카운트:", count)
count++
}
이 방식은 초기화 문이나 증감식이 필요 없을 때 코드를 아주 깔끔하게 만들어줘요. 조건식만 덩그러니 놓여 있어서 읽는 사람도 "아, 이 조건이 깨질 때까지 계속 돌아가겠구나"라고 바로 직관적으로 이해할 수 있죠.
STEP 5. 무한 루프와 정교한 탈출 전략
때로는 시작할 때 조건을 정하지 않고, 내부 로직에 따라 탈출 여부를 결정해야 할 때가 있어요. 이때는 조건식을 비워둔 채 for { ... }라고 쓰면 돼요. 이는 무한 루프를 의미해요. 다만, 반드시 내부 어딘가에는 탈출 조건이 있어야 해요.
for {
fmt.Println("서버 상태를 확인 중입니다...")
success := checkServer() // 서버 체크 함수라고 가정해요
if success {
fmt.Println("연결 성공!")
break // 성공했으니 반복을 끝내요
}
fmt.Println("재시도 중... 3초 후 다시 시도합니다.")
time.Sleep(3 * time.Second)
}
이런 패턴은 센서 데이터를 계속 읽어들이거나, 실시간 채팅 서버의 메시지를 대기할 때 자주 사용돼요.
무한 루프를 작성할 때는 반드시 break나 return이 실행될 수 있는 경로가 있는지 확인하세요. 그렇지 않으면 프로그램이 CPU 자원을 계속 잡아먹으며 폭주하게 됩니다.
자주 하는 실수와 해결법
반복문을 작성하다 보면 누구나 한 번쯤은 실수를 하게 마련이에요. Go 언어의 특성 때문에 발생하는 흔한 실수들을 정리했으니, 코드가 제대로 동작하지 않는다면 여기서 답을 찾아보세요.
- ❌ 인덱스 범위를 벗어나는 에러 (Index Out of Range)
왜 발생하는가: 반복문의 조건식을 설정할 때, 슬라이스의 길이를 잘못 계산하거나i <= len(slice)처럼 등호를 잘못 붙였을 때 발생해요.
✅ 해결법: 항상i < len(slice)와 같이 미만 연산자를 사용하세요. - ❌ 사용하지 않는 변수 선언 에러
왜 발생하는가:for i, v := range slice라고 썼는데 정작 코드 안에서i를 쓰지 않으면 컴파일 에러가 나요.
✅ 해결법: 필요 없는 변수는for _, v := range slice처럼 언더바(_)로 처리하세요. - ❌ 무한 루프의 늪
왜 발생하는가: 표준형 for 문에서 증감식(i++)을 빼먹거나, 조건식이 절대 false가 되지 않는 경우예요.
✅ 해결법: 반복문이 끝나는 조건이 명확한지, 매 루프마다 조건에 변화를 주는 코드가 있는지 확인하세요. - ❌ 반복문 변수 섀도잉 (Shadowing)
왜 발생하는가: 반복문 안에서 외부 변수와 똑같은 이름의 짧은 변수를 새로 선언(:=사용)하면 외부 변수 값이 바뀌지 않아요.
✅ 해결법: 반복문 내부에서는 기존 변수를 업데이트(=사용)하거나 이름을 다르게 지어주세요. - ❌ Range 루프 변수 공유 문제 (Go 1.22 미만 버전)
왜 발생하는가: 과거 버전의 Go에서는 range의 반복 변수가 루프가 돌아도 같은 메모리 주소를 공유했어요. 그래서 루프 안에서 포인터를 저장하면 모두 같은 값을 가리키게 되었죠.
✅ 해결법: 최신 Go 버전(1.22 이상)을 사용하거나, 반복문 안에서 변수를 새로 복사해서 사용하세요.
자주 묻는 질문
Q. Go에서 while 문을 대신할 때 가장 권장되는 방식은 무엇인가요?
조건 하나만 필요한 경우라면 for condition { ... } 형식을 사용하는 것이 가장 표준적이고 Go다운 방식이에요. 다른 언어의 while 문과 완전히 동일하게 동작하므로 걱정 없이 사용하셔도 돼요.
Q. range를 쓸 때 인덱스와 값을 모두 가져오지 않으면 에러가 나나요?
아니요, 그렇지 않아요! 값만 필요하다면 for _, value := range slice처럼 언더바를 사용해 인덱스를 생략하면 돼요. 반대로 인덱스만 필요하다면 for i := range slice라고 써도 된답니다.
Q. 중첩 반복문(Nested Loop)에서 바깥쪽 루프를 한 번에 탈출할 수 있나요?
Go에서는 Label 기능을 사용하면 가능해요. OuterLoop: for ...라고 이름을 붙여준 뒤, 안쪽에서 break OuterLoop라고 호출하면 바깥쪽 루프까지 한 번에 종료할 수 있어요.
Q. 맵(Map)을 range로 돌릴 때 순서가 매번 달라지는데 왜 그런가요?
Go의 맵은 내부적으로 순서를 보장하지 않도록 설계되어 있어요. 이는 무작위성을 통해 성능을 최적화하려는 Go의 철학 때문이에요. 만약 일정한 순서가 필요하다면 맵의 키(Key)들을 별도의 슬라이스에 담아 정렬한 뒤, 그 슬라이스를 바탕으로 반복문을 돌려야 해요.
효율적인 반복문 작성을 위한 마무리
오늘 우리는 Go 언어의 유일한 반복문인 for를 깊이 있게 살펴봤어요. 처음에는 문법이 하나뿐이라는 게 낯설 수 있지만, 익숙해지면 오히려 이 단순함이 얼마나 강력한 무기인지 깨닫게 될 거예요. 복잡한 문법을 외우는 것보다, 상황에 맞는 적절한 패턴을 선택하는 능력을 기르는 것이 더 중요해요.
- 표준형 for 문은 횟수가 정해진 반복에 사용하세요.
- 데이터 집합을 다룰 때는 가독성이 좋은
range를 적극 활용하세요. - 사용하지 않는 변수는 반드시
_(언더바)로 처리해야 컴파일 에러를 피해요. - 무한 루프를 작성할 때는 탈출 조건(break)이 확실한지 항상 점검하세요.
- 맵(Map) 순회 시 순서가 보장되지 않는다는 점을 꼭 기억하세요.
이제 이론은 충분해요. 직접 코드를 입력해 보는 것만이 진짜 실력을 만드는 유일한 방법이에요.
- 오늘 할 일: 위 예제 코드들을 직접 에디터에 타이핑하고 실행해 보세요.
- 이번 주 할 일: 본인이 작성 중인 프로젝트의 반복문 중
range로 바꿀 수 있는 부분이 있는지 찾아보세요. - 실행 직전 할 일: 반복문 안에서 변수 이름을 지을 때 외부 변수와 겹치지 않는지 다시 한번 확인하세요.
반복문 활용 중에 막히는 부분이나 이해가 안 되는 코드가 있다면 언제든 댓글로 남겨 주세요. 여러분의 학습을 응원하며, 함께 고민하고 답변드릴게요!
함께 읽으면 좋은 글: Go 반복문 완전 정복 가이드