
Go 반복문 for, 왜 다른 언어와 다를까요?
다른 프로그래밍 언어를 배우다가 Go(Golang)를 처음 접하면 당황스러운 순간이 찾아와요. 파이썬의 for나 자바의 while 문을 찾다가, Go의 코드에는 오직 for 하나뿐이라는 사실을 깨닫기 때문이에요. “어떻게 while 문 없이 반복을 수행하라는 거지?”라는 의문이 드는 건 아주 자연스러운 현상이에요.
Go는 복잡한 기능을 여러 개 만드는 대신, 하나의 강력한 도구를 극한으로 다듬는 방식을 선택했어요. 그 도구가 바로 for 반복문이에요. 이 문법 하나만 제대로 이해하면 조건문, 무한 루프, 배열 순회 등 모든 반복 상황을 처리할 수 있어요. 처음에는 단순해 보여도, 상황에 따라 변형되는 형태를 모르면 실전에서 버그를 만들기 쉬워요.
오늘 이 글에서는 Go 반복문의 기본기를 탄탄하게 다지고, 실무에서 바로 써먹을 수 있는 다양한 패턴을 정리해 드릴게요. 단순히 문법을 외우는 것이 아니라, 어떤 상황에 어떤 형태의 반복문을 써야 효율적인지 그 판단 기준을 세워 드릴게요.
이 글에서 배우게 될 핵심 내용
- 기본적인 C 스타일의 for 문법과 구성 요소
- 슬라이스와 맵을 다루는 range 기반 반복문 활용법
- while 문을 대신하는 조건식 기반 반복문 패턴
- 실전에서 실수하기 쉬운 인덱스 및 성능 문제 해결법
- 무한 루프를 안전하게 제어하는 break와 continue 전략
반복문을 시작하기 전 반드시 알아야 할 기본 개념
Go의 반복문을 능숙하게 다루기 위해서는 단순히 문법을 적는 법을 넘어, 컴퓨터가 반복을 처리하는 방식을 이해해야 해요. Go의 for 문은 매우 유연해서, 작성하는 방식에 따라 전혀 다른 성격의 루프가 돼요. 본격적인 코딩에 들어가기 전에, 우리가 어떤 도구를 사용할 수 있는지 그 선택지를 먼저 명확히 구분해 볼게요.
가장 먼저 기억해야 할 점은 Go에는 별도의 while 키워드가 없다는 사실이에요. 대신 for 키워드 뒤에 조건식만 붙이면 그것이 바로 while 문이 돼요. 또한, 데이터 구조인 슬라이스(Slice)나 배열(Array)을 순회할 때는 인덱스와 값을 동시에 가져오는 특별한 문법이 필요해요. 이 차이를 모르면 불필요하게 복잡한 코드를 짜게 되어 가독성을 해칠 수 있어요.
Go의 반복문은 구조가 매우 단순합니다. 초기화, 조건식, 후처리라는 세 가지 요소를 하나의 문장 안에 담거나, 상황에 맞춰 하나씩 생략하며 유연하게 사용할 수 있는 것이 특징이에요.
그럼 상황별로 어떤 반복문 형태를 선택하는 것이 가장 현명한지 비교해 볼까요? 아래 표를 통해 기준을 잡아보세요.
| 반복 유형 | 주요 특징 | 추천 사용 상황 |
|---|---|---|
| 표준형 (C-style) | 초기값, 조건, 증감식을 직접 제어 | 정해진 횟수만큼 반복하거나 인덱스 조절이 필요할 때 |
| 범위형 (Range) | 인덱스와 값을 자동으로 추출 | 슬라이스, 배열, 맵의 모든 요소를 순회할 때 |
| 조건형 (While-style) | 조건식이 참인 동안 계속 실행 | 반복 횟수가 불명확하고 특정 조건이 충족될 때까지 돌아야 할 때 |
| 무한 루프 (Infinite) | 조건 없이 계속 실행 | 서버 리스닝이나 백그라운드 프로세스 실행 시 |
위의 기준을 바탕으로, 이제 실제 코드에서 이들이 어떻게 구현되는지 단계별로 깊이 있게 파헤쳐 볼게요. 각 유형의 세밀한 차이를 이해하는 것이 고수가 되는 첫걸음이에요.
Go 반복문 실전 활용 STEP 5
이제 본격적으로 실전 코드를 통해 각 반복문의 문법과 활용법을 익혀볼게요. 각 단계는 실제 프로젝트에서 마주하게 될 시나리오를 바탕으로 구성했어요. 코드를 눈으로만 보지 말고, 머릿속으로 변수의 변화를 그려가며 읽어보세요.
STEP 1. 표준형 for 문으로 정확한 횟수 제어하기
가장 기초가 되는 형태예요. 프로그래밍을 처음 배울 때 접하는 C 언어 스타일과 매우 흡사해요. 이 방식은 반복을 시작하기 전 변수를 설정하고, 매 반복마다 조건을 검사하며, 한 단계가 끝날 때마다 변수를 변화시켜요.
예를 들어, 1부터 5까지 숫자를 출력하는 코드를 작성한다면 다음과 같아요.
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
여기서 i := 1은 시작점이고, i <= 5는 언제 멈출지를 결정하는 경계선이에요. 그리고 i++는 한 번 돌 때마다 값을 1씩 키워주죠. 이 세 요소 중 하나라도 빠지면 문법 오류가 나거나 무한 루프에 빠질 수 있으니 주의해야 해요. 특정 간격으로 건너뛰고 싶다면 i += 2처럼 작성하여 숫자를 조절할 수도 있어요.
STEP 2. range를 활용한 슬라이스 데이터 순회하기
실무에서는 숫자를 직접 세기보다 데이터 목록(슬라이스)을 하나씩 꺼내 쓰는 일이 훨씬 많아요. 이때 가장 강력한 도구가 바로 range예요. range를 사용하면 인덱스와 실제 값을 아주 깔끔하게 가져올 수 있어요.
위 코드에서 index는 0부터 시작하는 위치 정보이고, name은 그 위치에 담긴 실제 문자열이에요. 만약 인덱스가 필요 없고 값만 쓰고 싶다면, 언더스코어(
_)를 사용해 인덱스를 무시할 수 있어요. 이것은 Go의 매우 중요한 관례 중 하나예요.STEP 3. 조건식만 사용하는 while 스타일 루프
반복 횟수가 정해져 있지 않고, 어떤 특정한 사건이 발생할 때까지 계속 돌아야 한다면 어떻게 해야 할까요? Go에서는 for 문에서 초기화와 후처리 부분을 비우고 조건식만 남기면 됩니다. 이것이 바로 우리가 찾던 while 문이에요.
이 방식은 조건이 만족되지 않는 순간(energy가 0 이하가 되는 순간) 즉시 루프를 빠져나가요. 루프 안에서 조건을 변화시키는 로직(energy -= 3)이 반드시 포함되어야 한다는 점을 명명백백히 기억하세요. 그렇지 않으면 에너지는 영원히 10에 머물러 프로그램이 멈추지 않게 돼요.
STEP 4. 제어 흐름을 결정하는 break와 continue
반복문 도중 흐름을 끊거나 건너뛰어야 할 때가 있죠. break는 루프를 완전히 탈출할 때 사용하고, continue는 현재 차례만 건너뛰고 다음 반복으로 바로 넘어갈 때 사용해요.
💡 알아두기
중첩된 루프(루프 안에 루프가 있는 경우)에서 break를 사용하면, 가장 가까운(안쪽) 루프만 탈출해요. 바깥쪽 루프까지 한 번에 나가고 싶다면 '레이블(Label)'이라는 기능을 사용해야 합니다.예를 들어, 특정 조건의 데이터를 찾자마자 멈추고 싶다면 다음과 같이 작성해요.
위 시나리오에서 8을 만나는 순간, 뒤에 남은 9와 11은 검사하지 않고 루프가 종료돼요. 만약 짝수를 그냥 지나치고 다음 숫자로 넘어가고 싶었다면 break 대신 continue를 썼을 거예요.
STEP 5. 실전 응용: 맵(Map) 순회와 무한 루프 패턴
마지막으로 실무에서 자주 쓰이는 맵 순회와 무한 루프를 살펴볼게요. 맵은 순서가 보장되지 않는 데이터 구조이기 때문에, 반복문을 돌릴 때마다 결과의 순서가 매번 달라질 수 있다는 점을 꼭 염두에 두어야 해요.
무한 루프는 매우 강력하지만 위험해요. 반드시 루프 내부에서 탈출 조건(
break)이 명확하게 설계되어야 합니다. 그렇지 않으면 CPU 점유율이 치솟으며 시스템이 마비될 수 있어요.실전 시나리오: 데이터 처리 일정표
앞서 배운 내용들을 종합하여, 사용자 목록을 받아 특정 조건에 맞는 사용자에게만 알림을 보내는 가상의 일정을 짜볼게요.
- 데이터 준비: 사용자 구조체 슬라이스 생성
- 반복 시작:
range를 사용하여 전체 사용자 순회- 조건 검사:
if문으로 알림 대상인지 확인- 예외 처리: 알림 대상이 아닌 경우
continue로 다음 사용자로 이동- 완료: 모든 사용자를 처리하면 루프 자동 종료
이런 흐름으로 코드를 설계하면 매우 견고하고 읽기 쉬운 프로그램을 만들 수 있어요.
자주 하는 실수와 해결법
반복문을 작성하다 보면 누구나 실수를 합니다. 특히 Go 언어의 특성을 고려하지 않으면 눈에 보이지 않는 논리적 오류가 발생하기 쉬워요. 흔히 발생하는 패턴들을 정리해 드릴게요.
❌ 실수 1: 인덱스 범위 초과 (Index Out of Range)
왜 발생하는가: 반복문의 종료 조건을 설정할 때 슬라이스의 길이를 잘못 계산하여, 존재하지 않는 인덱스에 접근하려고 할 때 발생해요.
✅ 해결법: 반복문의 조건을i < len(slice)와 같이 슬라이스의 길이를 기준으로 엄격하게 설정하세요.❌ 실수 2: 무한 루프에 빠지는 경우
왜 발생하는가: 조건식에서 변수를 변화시키는 로직(증감식)을 빠뜨렸거나, 종료 조건에 도달할 수 없는 논리적 오류가 있을 때 발생해요.
✅ 해결법: 반복문이 끝나는 지점을 항상 눈으로 확인하고, 디버깅 시 변수의 값이 의도대로 변하는지 체크하세요.❌ 실수 3: range 루프 내에서 값의 복사 문제
왜 발생하는가:for _, val := range slice를 사용할 때,val은 슬라이스 요소의 '복사본'이에요. 즉,val의 값을 수정해도 실제 슬라이스 안의 데이터는 변하지 않아요.
✅ 해결법: 원본 데이터를 수정해야 한다면 인덱스를 사용하여slice[i] = newValue방식으로 직접 접근하세요.❌ 실수 4: 대규모 구조체 순회 시 성능 저하
왜 발생하는가: 슬라이스에 아주 큰 구조체가 담겨 있을 때,range를 쓰면 매 루프마다 큰 데이터가 복사되어 메모리와 CPU를 많이 사용해요.
✅ 해결법: 데이터가 크다면 값 대신 포인터 슬라이스를 사용하거나 인덱스로 접근하여 복사 비용을 줄이세요.❌ 실수 5: 맵(Map) 순회 순서에 대한 오해
왜 발생하는가: 맵을 반복문으로 돌리면 매번 순서가 달라지는데, 이를 고정된 순서라고 착각하여 로직을 짜면 결과가 매번 달라지는 버그가 생겨요.
✅ 해결법: 순서가 중요하다면 키(Key)를 별도의 슬라이스에 담아 정렬한 뒤, 그 슬라이스를 기준으로 맵을 순회하세요.자주 묻는 질문
Q. Go에는 정말 while 문이 아예 없나요?
네, 맞아요. 하지만 for 문이 조건식만 받으면 while 문처럼 동작하기 때문에, 굳이 별도의 키워드를 만들지 않은 것이에요. Go의 철학인 '단순함'을 잘 보여주는 대목이죠.Q. range를 쓸 때 인덱스가 필요 없으면 어떻게 하나요?
언더스코어(_)를 사용하시면 돼요.for _, value := range slice와 같이 작성하면 인덱스는 무시하고 값만 가져올 수 있어요.Q. 반복문 안에서 또 반복문을 쓰는 중첩 루프는 피해야 하나요?
필요하다면 사용해도 괜찮아요. 다만, 중첩이 너무 깊어지면(3단계 이상) 코드를 읽기가 매우 힘들어지므로, 내부 루프를 별도의 함수로 분리하는 것이 좋은 습관이에요.Q. for 루프를 한 줄로 쓸 수 있나요?
간단한 문장이라면 가능하지만, Go는 가독성을 중시하는 언어예요. 코드의 명확성을 위해 중괄호({ })를 사용하여 줄을 나누어 쓰는 것을 강력히 권장해요.Q. break를 쓰면 루프 전체가 끝나나요?
가장 가까운 루프 하나만 끝나요. 만약 바깥쪽 루프까지 한꺼번에 종료하고 싶다면 레이블(Label) 기능을 사용해야 해요.Go 반복문 마스터를 위한 마지막 체크리스트
오늘 우리는 Go 언어의 유일한 반복 도구인 for 문의 모든 얼굴을 살펴보았어요. 처음에는 생소할 수 있지만, 이 문법들이 서로 어떻게 연결되는지 이해했다면 여러분은 이미 Go 개발자로서 큰 발걸음을 뗀 거예요. 반복문은 단순한 반복을 넘어 프로그램의 흐름을 결정하는 심장과 같다는 점을 잊지 마세요.
✅ 핵심 요약
- 표준형(C-style)은 정해진 횟수와 세밀한 인덱스 제어에 최적이에요.
- range는 슬라이스와 맵을 쉽고 안전하게 순회할 때 필수예요.
- while 문이 필요할 땐 for 뒤에 조건식만 남기면 돼요.
- 데이터 수정이 목적이라면 range의 값(Value) 대신 인덱스(Index)를 사용하세요.
- 무한 루프를 사용할 때는 반드시 안전한 탈출 조건(break)을 설계하세요.
- 맵(Map) 순회는 순서가 매번 바뀐다는 점을 반드시 기억하세요.
이제 이론은 충분해요. 직접 손을 움직여 코드를 작성해 볼 시간이에요. 오늘 배운 내용을 바탕으로 아래의 단계들을 실천해 보세요.
- 오늘 할 일: 직접 IDE를 켜고 1부터 100까지의 숫자 중 짝수만 출력하는 for 문을 작성해 보세요.
- 이번 주 할 일: 간단한 이름 슬라이스를 만들고, range를 이용해 각 이름 앞에 "안녕하세요, "를 붙여 출력하는 연습을 해보세요.
- 실행 직전 할 일: 복잡한 중첩 루프를 만났을 때, 어떻게 함수로 분리할지 미리 머릿속으로 그려보세요.
Go 프로그래밍을 공부하다가 막히는 부분이 있거나, 특정 반복 패턴이 이해되지 않는다면 언제든 아래 댓글로 질문을 남겨 주세요. 함께 고민하고 답변해 드릴게요! 여러분의 성장을 응원합니다.
함께 읽으면 좋은 글: Go 반복문 for 완벽 가이드