
Go 프로그래밍의 핵심, 반복문 정복하기
자바나 파이썬 같은 다른 언어를 배우다가 Go 언어에 입문하면 가장 먼저 당황하는 지점이 있어요. 바로 while 문이 보이지 않는다는 사실이에요. 반복을 처리하고 싶은데 도대체 어떤 키워드를 써야 할지 몰라 코드를 작성하다가 멈칫했던 경험, 아마 한 번쯤은 있으실 거예요.
Go는 다른 언어들처럼 복잡하게 여러 종류의 반복문을 제공하지 않아요. 대신 단 하나의 키워드인 for를 사용해 모든 반복 로직을 처리하도록 설계되었어요. 처음에는 이 단순함이 오히려 낯설고 어렵게 느껴질 수 있지만, 이 규칙에 익숙해지면 코드가 훨씬 깔끔해지고 읽기 쉬워진다는 것을 곧 깨닫게 될 거예요.
반복문을 제대로 다루지 못하면 무한 루프에 빠져 프로그램이 멈추거나, 슬라이스의 인덱스 범위를 벗어나 에러가 발생하는 낭패를 볼 수 있어요. 특히 대규모 데이터를 처리하는 Go의 특성상, 효율적인 반복문 사용은 프로그램의 성능과 직결되는 아주 중요한 문제예요.
이 글을 끝까지 읽고 나면 여러분은 더 이상 while 문을 찾아 헤매지 않아도 돼요. Go 반복문 치트시트를 통해 상황에 맞는 최적의 문법을 골라 쓰는 능력을 갖추게 될 거예요. 실무에서 바로 써먹을 수 있는 다양한 패턴과 주의사항까지 모두 담았으니 천천히 따라와 주세요.
이 글에서 다루는 핵심 내용
- Go의 유일한 반복문인 for의 다양한 활용 문법
- 슬라이스, 맵, 문자열을 순회하는 range 키워드 활용법
- 무한 루프와 제어문(break, continue) 사용 패턴
- 초보 개발자가 가장 자주 범하는 실수와 해결책
반복문 사용 전 꼭 알아야 할 기초 지식
Go의 반복문을 본격적으로 배우기 전에, 왜 Go가 이런 구조를 선택했는지 이해하는 것이 중요해요. Go 설계자들은 언어의 복잡성을 줄이고 가독성을 높이기 위해 최소한의 키워드를 사용하는 철학을 가지고 있어요. for 하나만 제대로 알아도 모든 반복 작업을 수행할 수 있다는 뜻이에요.
반복문을 작성할 때는 내가 처리하려는 데이터가 무엇인지, 그리고 언제 반복을 멈춰야 하는지를 명확히 결정해야 해요. 단순히 숫자를 세는 것인지, 아니면 데이터 집합의 끝까지 훑어야 하는지에 따라 사용하는 문법이 달라지기 때문이에요.
Go에는
while 문이 따로 없어요. while 문이 필요한 상황에서도 모두 for를 사용하며, 조건식만 넣으면 while과 똑같이 동작해요.상황별 반복문 선택 기준
모든 상황에 똑같은 반복문을 쓰는 것은 효율적이지 않아요. 아래 표를 보고 지금 내 코드에 어떤 방식이 가장 적합할지 판단해 보세요.
| 반복 방식 | 주요 용도 | 추천 상황 |
|---|---|---|
| 기본형 for | 카운트 기반 반복 | 특정 횟수만큼 반복할 때 |
| 조건형 for | 조건부 반복 (while 대용) | 특정 조건이 충족될 때까지 실행할 때 |
| range 활용형 | 컬렉션 순회 | 슬라이스, 맵, 문자열을 다룰 때 |
| 무한 루프 | 지속적 작업 수행 | 서버 리스너나 워커 풀을 구현할 때 |
이처럼 Go의 반복문은 매우 유연해요. 하지만 유연하다는 것은 그만큼 개발자가 신경 써야 할 부분이 많다는 의미이기도 해요. 예를 들어, 반복문의 종료 조건을 잘못 설정하면 프로그램이 영원히 끝나지 않는 무한 루프에 빠질 위험이 있어요. 따라서 코드를 작성하기 전에 반복의 시작과 끝을 논리적으로 설계하는 습관을 들여야 해요.
Go 반복문 실전 활용 가이드
이제 실제 코드를 어떻게 작성하는지 단계별로 살펴볼게요. 각 단계는 가장 기초적인 문법부터 실무에서 자주 쓰이는 고급 패턴까지 포함하고 있어요. Go 반복문 치트시트의 핵심이니 집중해서 확인해 주세요.
STEP 1. 가장 표준적인 3요소 반복문
C 언어나 Java 스타일의 전통적인 반복 방식이에요. for 키워드 뒤에 세 가지 요소가 세미콜론(;)으로 구분되어 들어가요. 첫 번째는 초기화 문장, 두 번째는 조건식, 세 번째는 증감 문장이에요.
이 구조는 반복 횟수를 명확하게 제어하고 싶을 때 가장 유용해요. 예를 들어 1부터 10까지 숫자를 출력하고 싶다면, 변수 i를 1로 시작하고, i가 10 이하인 동안 실행하며, 매번 i를 1씩 증가시키도록 설정하면 돼요. 구조가 정형화되어 있어서 코드를 읽는 사람이 몇 번 반복될지 한눈에 파악하기 매우 좋답니다.
STEP 2. 조건식만 사용하는 while 스타일
Go에는 while이라는 키워드가 없지만, for 키워드 뒤에 조건식만 적어주면 똑같은 역할을 수행해요. 이는 특정 조건이 참(true)인 동안 계속해서 작업을 수행해야 할 때 사용해요. 예를 들어 데이터 스트림에서 읽어온 값이 0이 아닐 때까지 계속 읽어들이는 로직을 짤 때 아주 적합해요.
이 방식은 반복 횟수가 정해져 있지 않고, 데이터의 상태에 따라 종료 시점이 결정될 때 사용하세요. 초기화 문장과 증감 문장을 생략할 수 있어 코드가 매우 간결해지는 장점이 있어요. 다만, 조건식이 언제 false가 될지 논리적으로 완벽하게 설계하지 않으면 무한 루프에 빠질 수 있으니 주의가 필요해요.
STEP 3. 무한 루프와 제어문 활용하기
조건식 없이 for만 적으면 프로그램은 멈추지 않고 계속 실행돼요. 이를 무한 루프라고 불러요. 보통 서버 애플리케이션에서 클라이언트의 요청을 계속 기다리거나, 백그라운드에서 주기적으로 작업을 수행하는 워커(Worker)를 만들 때 사용해요.
무한 루프를 안전하게 사용하려면 반드시 break나 continue 문을 적절히 섞어 써야 해요. break는 반복문을 즉시 종료하고 빠져나오게 하며, continue는 현재 차례의 나머지 코드를 건너뛰고 다음 반복으로 바로 넘어가게 해줘요. 특정 조건에서 작업을 중단하거나 건너뛰어야 하는 실무 로직에서 이 두 제어문은 필수적이에요.
STEP 4. range를 이용한 컬렉션 순회
Go 개발자들이 가장 사랑하는 문법 중 하나가 바로 range예요. 슬라이스(Slice), 맵(Map), 문자열(String) 같은 데이터 집합을 하나씩 꺼내올 때 사용해요. range를 사용하면 인덱스와 값을 한 번에 가져올 수 있어 코드가 매우 직관적이고 안전해요.
슬라이스를 순회할 때는 index, value 형태로 값을 받아요. 맵을 순회할 때는 key, value 형태로 데이터를 꺼내게 돼요. 여기서 한 가지 흥미로운 점은 맵을 순회할 때는 순서가 보장되지 않는다는 사실이에요. 매번 실행할 때마다 순서가 달라질 수 있으니, 순서가 중요한 작업에는 맵 대신 슬라이스를 사용해야 해요.
특히 문자열을 다룰 때는 range의 강력함을 체감할 수 있어요. Go의 range는 문자열을 단순히 바이트 단위로 자르는 게 아니라, UTF-8 기반의 룬(rune) 단위로 처리해요. 덕분에 한글처럼 여러 바이트를 차지하는 문자도 깨지지 않고 정확하게 하나씩 읽어올 수 있답니다. 문자열 처리가 많은 프로젝트라면 반드시 range를 활용하는 습관을 들이세요.
STEP 5. 중첩 반복문과 성능 최적화
반복문 안에 또 다른 반복문을 넣는 중첩 루프 구조도 자주 쓰여요. 2차원 배열을 탐색하거나, 여러 데이터 세트를 비교할 때 필수적이죠. 하지만 중첩 루프를 사용할 때는 항상 시간 복잡도를 고민해야 해요. 반복문이 겹칠수록 실행 시간은 기하급수적으로 늘어나거든요.
예를 들어 데이터가 1,000개인 슬라이스 두 개를 중첩 루프로 비교하면 총 1,000,000번의 연산이 발생해요. 데이터 양이 많아질수록 프로그램이 눈에 띄게 느려질 수 있어요. 따라서 대량의 데이터를 다룰 때는 중첩 루프 대신 맵(Map)을 활용해 조회 성능을 높이는 등 알고리즘적인 접근을 함께 고려하는 것이 실력 있는 개발자로 가는 길이에요.
반복문 내에서 변수의 주소를 참조할 때, 특히
range를 사용할 때는 변수의 재사용 방식에 주의해야 해요. Go 1.22 버전 이후로는 이 문제가 많이 개선되었지만, 구버전 환경에서는 여전히 주의가 필요한 부분이에요.자주 하는 실수와 해결법 및 FAQ
실전 코딩 중에 마주칠 수 있는 당혹스러운 상황들을 미리 정리해 드릴게요. 실수를 미리 알고 있다면 디버깅 시간을 획기적으로 줄일 수 있어요.
자주 하는 실수와 해결법
❌ 실수: 인덱스 범위 초과 (Out of Bounds)
왜 발생하는가: 반복 조건식에서 `<` 대신 `<=`를 사용하여 슬라이스의 마지막 인덱스보다 큰 값을 참조하려고 할 때 발생해요.
✅ 해결법: 슬라이스의 길이를 사용할 때는 반드시 `i < len(slice)`와 같이 미만 연산자를 사용하세요.
❌ 실수: 무한 루프 발생
왜 발생하는가: `for` 문의 조건식이 항상 참이거나, 루프 내부에서 조건 변수를 업데이트하는 로직을 빠뜨렸을 때 발생해요.
✅ 해결법: 루프가 종료될 수 있는 명확한 탈출 조건(Exit Condition)을 설정하고, `break` 문을 적절히 배치하세요.
❌ 실수: range 변수 포인터 문제
왜 발생하는가: range로 가져온 변수의 주소를 슬라이스에 저장할 때, 모든 슬라이스 요소가 루프의 마지막 변수 주소만 가리키게 되는 현상이에요.
✅ 해결법: 루프 내부에서 변수를 새로운 변수에 복사한 뒤 그 복사본의 주소를 사용하세요.
❌ 실수: 맵 순회 시 순서 의존
왜 발생하는가: 맵은 순서가 없는 자료구조인데, 루프를 돌 때마다 결과가 달라질 것이라고 가정하고 코드를 짤 때 발생해요.
✅ 해결법: 순서가 중요하다면 키(Key)들을 슬라이스에 먼저 담아 정렬한 뒤, 그 슬라이스를 기준으로 맵에 접근하세요.
❌ 실수: 불필요한 중첩 루프 사용
왜 발생하는가: 간단한 검색 작업임에도 불구하고 이중, 삼중으로 반복문을 중첩하여 성능을 저하시키는 경우예요.
✅ 해결법: 데이터 검색이 잦다면 맵을 활용해 시간 복잡도를 $O(n)$에서 $O(1)$로 낮추는 방법을 고민해 보세요.
자주 묻는 질문
Q. for 문 안에서 break와 continue의 차이점이 무엇인가요?
break는 반복문 전체를 즉시 종료하고 루프 밖으로 빠져나가는 명령이에요. 반면 continue는 현재 진행 중인 차례만 중단하고, 다음 반복 단계로 바로 건너뛰게 만드는 명령이에요. 작업을 완전히 멈출지, 아니면 이번 것만 건너뛸지의 차이예요.
Q. Go에서 while 문을 대신해서 for 문을 어떻게 쓰나요?
for condition { ... } 형식을 사용하면 돼요. 조건식이 참인 동안에만 중괄호 안의 코드가 실행되므로, 우리가 흔히 아는 while 문과 완벽하게 동일하게 작동해요.
Q. range를 쓸 때 index와 value를 모두 안 써도 되나요?
네, 가능해요. 만약 값(value)만 필요하다면 for _, value := range slice처럼 언더스코어(_)를 사용해 인덱스를 무시할 수 있어요. 반대로 인덱스만 필요하다면 for i := range slice라고만 적어도 돼요.
Q. 문자열을 byte 단위가 아닌 글자 단위로 읽으려면 어떻게 하나요?
반드시 range 키워드를 사용하세요. for i := 0; i < len(s); i++ 방식은 바이트 단위로 접근하지만, for index, runeValue := range s 방식은 UTF-8 문자를 인식하여 글자 단위로 처리해 줍니다.
Q. 무한 루프를 만드는 가장 간단한 방법은 무엇인가요?
조건식 없이 for { ... }라고만 작성하면 돼요. 이 루프는 내부에 break 명령어가 나타나기 전까지는 영원히 멈추지 않아요.
반복문 마스터를 위한 최종 정리
오늘 배운 내용을 잊지 않도록 핵심만 다시 한번 짚어볼까요? 이 리스트를 화면 옆에 띄워두고 코딩할 때 참고해 보세요.
- Go에는
for하나로 모든 반복을 처리해요. - 전통적인 카운트 방식은 3요소(초기화, 조건, 증감)를 사용해요.
while문이 필요할 땐for뒤에 조건식만 적으세요.- 컬렉션 순회에는
range를 쓰는 것이 가장 안전하고 편리해요. - 문자열은
range를 써야 한글이 깨지지 않아요. - 무한 루프를 만들 때는
break로 탈출구를 꼭 만드세요.
반복문은 프로그래밍의 가장 기본이면서도 가장 강력한 도구예요. 처음에는 문법이 낯설 수 있지만, 직접 코드를 작성하며 다양한 상황을 테스트해 보다 보면 어느덧 자연스럽게 손에 익게 될 거예요. 이론으로 아는 것과 직접 타이핑하며 에러를 마주하는 것은 큰 차이가 있으니까요.
오늘 바로 실천할 체크리스트
- 내 코드에 불필요한
while스타일 루프가 있다면range로 바꿀 수 없는지 검토하기 - 중첩 루프를 사용 중이라면 시간 복잡도를 계산해 보고 최적화할 방법 찾기
- 문자열 처리 시
range를 제대로 사용하고 있는지 확인하기
오늘 정리해 드린 Go 반복문 치트시트가 여러분의 학습에 큰 도움이 되었기를 바라요. 혹시 코드를 짜다가 막히는 부분이나 이해가 안 되는 개념이 있다면 주저하지 말고 아래 댓글로 질문을 남겨 주세요. 함께 고민하고 답변해 드릴게요!
더 깊이 있는 Go 프로그래밍 학습을 원하신다면, Go 반복문 완전 정복 가이드 글도 함께 읽어 보시는 것을 추천해 드려요.