[IT-정보] Go 반복문 치트시트: 핵심 문법 완벽 정리 – 입문자를 위한 실전 예제와 패턴 가이드

반복문 for 개념을 시각화한 Go 프로그래밍 일러스트

왜 Go의 반복문은 하나뿐일까요?

다른 프로그래밍 언어를 배우다가 Go(Golang)의 세계로 넘어오면 가장 먼저 당황하는 지점이 있어요. 바로 반복문 종류가 딱 하나뿐이라는 사실이에요. 파이썬의 for나 while, 자바의 다양한 루프 구조에 익숙해진 분들에게는 처음엔 무언가 빠진 것처럼 느껴질 수도 있어요.

하지만 이것은 Go의 철학을 그대로 보여주는 대목이에요. 복잡함을 덜어내고 단 하나의 강력한 도구인 for 키워드만으로 모든 상황을 해결하도록 설계되었거든요. 처음에는 이 단순함이 어떻게 모든 복잡한 로직을 처리할 수 있는지 의문이 들 수 있지만, 익숙해지면 오히려 코드의 가독성이 높아지는 경험을 하게 될 거예요.

많은 입문자가 반복문을 돌리다가 인덱스 범위를 벗어나 에러를 겪거나, 맵(map)을 순회할 때 값이 예상과 다르게 나와 당황하곤 해요. 특히 슬라이스(slice)를 다룰 때 조건식을 잘못 작성하면 프로그램이 바로 멈춰버리기도 하죠. 이런 사소하지만 치명적인 실수들은 반복문의 동작 원리를 정확히 이해하지 못했을 때 발생해요.

이 글을 끝까지 읽고 나면 여러분은 더 이상 반복문 문법을 검색하며 시간을 허비하지 않아도 돼요. Go 반복문 치트시트를 통해 기초부터 고급 패턴까지 완벽하게 마스터할 수 있거든요. 실무에서 자주 쓰이는 스니펫과 주의사항까지 정리했으니, 이 글 하나로 반복문 고민을 끝내보세요.

이 글에서 함께 살펴볼 내용이에요

  • 가장 기본이 되는 표준 for 문법과 동작 원리
  • 슬라이스, 배열, 맵을 효율적으로 순회하는 range 활용법
  • 실전 프로젝트에서 바로 복사해서 쓰는 유용한 코드 패턴
  • 초보자가 가장 많이 하는 실수와 그에 대한 명쾌한 해결책

반복문을 쓰기 전 꼭 알아야 할 기초 지식

Go의 반복문을 제대로 활용하려면 먼저 제어 흐름의 메커니즘을 머릿속에 그려두어야 해요. Go는 다른 언어처럼 while이나 do-while 같은 별도의 키워드를 제공하지 않아요. 모든 것은 for 하나로 통제된다는 점을 명심해야 해요.

반복문을 작성하기 전에 여러분이 어떤 상황에 놓여 있는지 먼저 판단해야 해요. 단순히 숫자를 세고 싶은 것인지, 아니면 데이터 꾸러미인 슬라이스를 하나씩 꺼내보고 싶은 것인지에 따라 사용하는 문법이 완전히 달라지거든요. 상황에 맞지 않는 방식을 선택하면 코드가 불필요하게 길어지거나 성능이 저하될 수 있어요.

💡 알아두기
Go에서 for 문은 세 가지 핵심 요소인 초기화(initialization), 조건식(condition), 후처리(post)를 가질 수 있어요. 이 요소들은 모두 생략이 가능하며, 모두 생략하면 무한 루프가 실행돼요.

아래 표를 통해 상황별로 어떤 형태의 for 문을 선택하는 것이 가장 현명한지 비교해 볼게요. 이 기준을 머릿속에 넣어두면 코드 작성 속도가 몰라보게 빨라질 거예요.

사용 상황 추천 문법 형태 핵심 장점
정해진 횟수만큼 반복할 때 for (초기화; 조건; 후처리) 인덱스 제어가 매우 정밀함
슬라이스/맵/채널 순회 for range 가독성이 높고 실수를 방지함
조건이 충족될 때까지 반복 for (조건식) while 문과 동일한 역할 수행
무한히 실행해야 할 때 for (빈 칸) 서버 리스닝 등 지속 작업에 적합

준비를 마쳤다면 이제 본격적으로 코드의 세계로 들어가 볼까요? 단순한 문법 나열이 아니라, 실제 어떻게 코드가 돌아가는지 단계별로 깊이 있게 파헤쳐 볼게요.

Go 반복문 마스터를 위한 단계별 실전 가이드

이제 본격적으로 Go 반복문의 핵심을 단계별로 알아볼게요. 단순히 문법을 외우는 것이 아니라, 각 단계가 어떤 논리로 동작하는지를 이해하는 것이 중요해요.

STEP 1. 가장 클래식한 표준 for 문법 이해하기

가장 먼저 살펴볼 것은 C 언어 스타일의 전통적인 방식이에요. 이 방식은 세 가지 구성 요소를 세미콜론(;)으로 구분하여 한 줄에 작성해요. 구조는 `for 초기화; 조건식; 후처리 { … }` 형태예요.

여기서 초기화 단계는 루프가 시작될 때 딱 한 번만 실행돼요. 조건식은 매 반복이 시작되기 직전에 확인하며, 이 조건이 참(true)일 때만 중괄호 안의 코드가 실행돼요. 마지막으로 후처리 단계는 루프 본문이 끝난 직후에 실행되어 변수의 값을 업데이트하죠. 이 일련의 흐름을 정확히 이해해야 무한 루프에 빠지지 않아요.

💡 알아두기
조건식을 생략하면 `for { … }` 형태가 되어 조건 없이 계속 반복되는 무한 루프가 돼요. 특정 조건에서 `break`를 사용하여 탈출해야 안전해요.

이 방식은 인덱스를 직접 조작해야 하거나, 증가 폭을 2씩 늘려야 하는 경우처럼 매우 세밀한 제어가 필요할 때 아주 강력한 힘을 발휘해요.

STEP 2. range를 이용한 스마트한 데이터 순회

Go를 쓰는 가장 큰 이유 중 하나는 바로 range 키워드의 편리함이에요. 슬라이스(slice), 배열(array), 맵(map), 문자열(string)을 순회할 때 인덱스를 일일이 계산할 필요 없이 아주 깔끔하게 작성할 수 있어요.

슬라이스나 배열을 사용할 때 `for index, value := range slice` 형식을 쓰면, 현재 몇 번째 요소인지 알려주는 인덱스와 그 안에 담긴 실제 값을 동시에 얻을 수 있어요. 만약 인덱스만 필요하다면 `for i := range slice`라고 써도 되고, 값만 필요하다면 인덱스 자리에 밑줄(`_`)을 써서 무시할 수 있어요.

맵(map)을 순회할 때는 인덱스 대신 키(key)와 값(value)이 반환돼요. 여기서 주의할 점은 맵의 순회 순서는 매번 실행할 때마다 달라질 수 있다는 점이에요. 맵은 순서가 보장되지 않는 자료구조라는 사실을 꼭 기억하세요.

STEP 3. 흐름을 제어하는 break와 continue

반복문을 돌리다 보면 중간에 멈춰야 하거나, 특정 조건에서는 건너뛰고 싶을 때가 있어요. 이때 사용하는 것이 바로 `break`와 `continue`예요.

`break`는 반복문을 즉시 완전히 종료하고 루프 밖으로 빠져나오게 해요. 특정 데이터를 찾았을 때 더 이상 루프를 돌릴 필요가 없다면 `break`를 사용해 자원을 아껴야 해요. 반면 `continue`는 현재 진행 중인 반복 회차의 남은 코드를 무시하고 곧바로 다음 반복의 조건 확인 단계로 넘어가는 역할을 해요. 특정 조건에 맞는 데이터만 걸러내고 싶을 때 유용하죠.

STEP 4. 중첩 루프와 라벨(Label) 활용 기술

가끔 루프 안에 루프가 들어있는 중첩 구조를 다룰 때가 있어요. 일반적인 `break`는 자신을 감싸고 있는 가장 가까운 루프 하나만 탈출시켜요. 하지만 만약 두 단계 위의 루프까지 한꺼번에 탈출해야 한다면 어떻게 해야 할까요?

이때 Go의 강력한 기능인 라벨(Label)을 사용해요. 루프 앞에 `OuterLoop:` 같은 이름을 붙여주고, `break OuterLoop`라고 명시하면 중첩된 모든 루프를 한 번에 빠져나갈 수 있어요. 이 기능을 알면 복잡한 알고리즘을 훨씬 간결하게 구현할 수 있어요.

STEP 5. 실전 시나리오: 조건부 데이터 필터링

실무에서 가장 흔히 쓰이는 패턴 중 하나는 슬라이스에서 특정 조건을 만족하는 데이터만 추출하는 것이에요. 아래는 사용자의 나이 목록에서 성인(20세 이상)만 골라내는 로직을 시뮬레이션한 시나리오예요.

먼저 정수형 슬라이스를 준비해요. 그리고 `for range`를 사용하여 각 나이 값을 확인해요. 만약 값이 20보다 작다면 `continue`를 사용하여 해당 회차를 건너뛰고, 20 이상인 경우에만 결과 슬라이스에 추가하는 방식이에요. 이렇게 하면 복잡한 `if-else` 문을 길게 늘어뜨리지 않고도 아주 명확한 코드를 작성할 수 있어요.

⚠️ 주의
반복문 안에서 루프의 대상이 되는 슬라이스를 직접 수정(요소 삭제 등)하면 인덱스가 꼬여서 예기치 못한 동작이 발생할 수 있어요. 삭제가 필요하다면 새로운 슬라이스를 만드는 방식을 권장해요.

자주 하는 실수와 해결법 및 FAQ

반복문을 작성하다 보면 누구나 실수를 해요. 특히 Go는 엄격한 타입을 지향하기 때문에 사소한 차이가 큰 에러로 이어지기도 하죠. 실무에서 가장 많이 발생하는 문제들을 정리해 봤어요.

자주 하는 실수와 해결법

  • 인덱스 범위 초과 (Index Out of Range)
    왜 발생하는가: `for i := 0; i <= len(slice); i++`처럼 조건식에 `=`를 넣으면 슬라이스의 마지막 인덱스보다 하나 더 큰 값에 접근하려고 하기 때문이에요.
    ✅ 해결법: 조건을 항상 `i < len(slice)`로 작성하여 범위를 엄격히 제한하세요.
  • range 루프 내 변수 섀도잉 (Shadowing)
    왜 발생하는가: `for i, v := range slice`에서 사용하는 `v`는 매 반복마다 값이 복사되는 것이지, 슬라이스 내부의 메모리 주소를 가리키는 것이 아니에요.
    ✅ 해결법: 슬라이스의 실제 값을 수정해야 한다면 `range`로 얻은 인덱스를 사용하여 `slice[i] = newValue` 방식으로 접근하세요.
  • 무한 루프에 의한 리소스 고갈
    왜 발생하는가: `for` 문의 탈출 조건이 절대 참이 될 수 없거나, `break` 문이 누락되었을 때 발생해요.
    ✅ 해결법: 루프를 설계할 때 반드시 종료 조건을 먼저 정의하고, 탈출 로직이 모든 경로에서 실행되는지 검토하세요.
  • 맵 순회 순서에 의존하는 로직
    왜 발생하는가: Go의 맵은 순서가 무작위예요. 어제는 A, B 순서로 나왔는데 오늘은 B, A 순서로 나올 수 있어요.
    ✅ 해결법: 순서가 중요하다면 맵의 키들을 별도의 슬라이스에 담아 정렬한 뒤, 그 슬라이스를 기준으로 순회하세요.
  • 대규모 데이터 처리 시 성능 저하
    왜 발생하는가: 반복문 안에서 매번 큰 메모리 할당을 수행하거나 복잡한 함수를 호출하면 속도가 급격히 느려져요.
    ✅ 해결법: 루프 외부에서 필요한 변수를 미리 할당(Pre-allocation)하여 재사용하세요.

자주 묻는 질문

Q. Go에는 while 문이 없는데 어떻게 구현하나요?

Go에서는 `for` 키워드 하나로 모두 해결할 수 있어요. `for 조건식 { … }` 형태를 사용하면 우리가 흔히 아는 `while` 문과 완벽하게 동일하게 동작해요.

Q. range를 쓸 때 인덱스가 필요 없으면 어떻게 하나요?

인덱스 자리에 빈 식별자인 언더스코어(`_`)를 사용하면 돼요. 예를 들어 `for _, value := range slice`라고 쓰면 인덱스는 무시하고 값만 가져올 수 있어요.

Q. 중첩된 for 문을 한 번에 빠져나가고 싶을 땐 어떻게 하죠?
라벨을 사용하면 아주 간단해요. 루프 시작 부분에 `Outer: `라고 이름을 붙인 뒤, 탈출하고 싶은 곳에서 `break Outer`라고 명령하면 돼요.

Q. 맵(map)을 순회할 때 키(key)만 가져올 수 있나요?

네, 가능해요. `for key := range myMap`이라고 작성하면 값은 제외하고 키값만 반복해서 받아올 수 있어요.

Q. 반복문 안에서 goroutine을 생성할 때 주의할 점이 있나요?

매우 중요한 질문이에요! 루프 변수를 고루틴의 인자로 직접 전달하지 않으면, 모든 고루틴이 루프의 마지막 값만 참조하는 대참사가 일어날 수 있어요. 반드시 고루틴의 매개변수로 현재 변수 값을 복사해서 전달해야 해요.

핵심 요약과 다음 단계

오늘 배운 내용을 한눈에 정리해 드릴게요. 이 내용만 기억해도 Go 프로그래밍의 절반은 성공한 셈이에요.

✅ 핵심 요약

  • Go의 반복문은 오직 for 하나뿐이며, 모든 형태를 커버해요.
  • 정밀한 제어가 필요할 땐 표준 for 문을, 데이터 순회 시엔 range를 쓰세요.
  • 슬라이스 값을 수정할 때는 인덱스를 통해 직접 접근해야 해요.
  • 중첩 루프 탈출은 라벨(Label) 기능을 활용하면 깔끔해요.
  • 맵 순회는 순서가 보장되지 않는다는 점을 항상 염두에 두세요.
  • 고루틴 사용 시 루프 변수의 복사본을 전달하는 것을 잊지 마세요.

자, 이제 이론은 충분해요. 이제 여러분이 직접 코드를 칠 차례예요!

오늘 바로 실행해 보세요

  • 직접 VS Code를 켜고 1부터 100까지 더하는 for 문을 작성해 보세요.
  • 슬라이스를 만들고 range를 사용해 요소들을 하나씩 출력해 보세요.
  • 맵을 생성하고 키와 값을 무작위로 출력하는 연습을 해보세요.

더 깊이 있는 Go 프로그래밍을 원하신다면, Go 반복문 완전 정복 가이드 글을 함께 읽어 보시는 것을 강력히 추천해요. 문법을 넘어 동작 원리까지 더 깊게 이해할 수 있을 거예요.

공부하시다가 막히는 부분이나 이해가 안 되는 코드가 있다면 언제든 댓글로 질문을 남겨 주세요. 제가 확인하는 대로 친절하게 답변해 드릴게요. 여러분의 즐거운 코딩 생활을 응원합니다!

댓글 남기기