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

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

반복문 for, 왜 Go에서는 유일한 선택일까요?

다른 언어를 공부하다 Go(Golang)로 넘어온 분들이 가장 먼저 당황하는 지점이 있어요. 바로 while이나 do-while 같은 반복문이 보이지 않는다는 사실이에요. Go는 설계 단계부터 복잡성을 줄이기 위해 오직 for 문 하나만 남겨두기로 결정했거든요.

처음에는 “어떻게 while 문 없이 코딩을 하지?”라는 의문이 생길 수 있어요. 하지만 Go의 for 문은 유연성이 굉장히 뛰어나서, 기존의 다양한 반복 문법을 모두 대체할 수 있어요. 오히려 문법이 단순해지면서 코드가 훨씬 깔끔해지고 읽기 쉬워지는 장점도 있죠.

이 글을 읽고 나면 여러분은 상황에 맞는 최적의 반복 구조를 선택할 수 있게 돼요. 복잡한 루프 로직 때문에 머리를 싸매던 시간은 이제 끝이에요. Go 반복문 치트시트를 통해 실무에서 즉시 활용 가능한 패턴을 완벽하게 익혀 보세요.

이 가이드에서는 다음과 같은 내용을 구체적으로 다뤄요.

  • 가장 기본적인 C 스타일의 for 루프 사용법
  • slice와 map을 효율적으로 훑는 range 문법
  • 무한 루프를 제어하는 break와 continue 전략
  • 실무에서 자주 실수하는 오류와 해결 방법

Go 반복문을 시작하기 전 꼭 알아야 할 기초 지식

Go의 for 문을 제대로 다루기 위해서는 몇 가지 사전 지식이 필요해요. 무작정 코드를 타이핑하기 전에, Go가 반복을 처리하는 방식과 기본 문법 요소를 이해하는 것이 중요해요. 이를 통해 나중에 발생할 수 있는 논리적 오류를 미연에 방지할 수 있어요.

반복문 구성의 3요소

전형적인 C 스타일의 for 문은 세 가지 구성 요소를 가져요. 이 구조를 이해하면 어떤 복잡한 루프도 설계할 수 있어요.

  • 초기화(Init): 루프가 시작될 때 딱 한 번 실행되는 부분이에요. 주로 반복 횟수를 셀 변수를 선언해요.
  • 조건식(Condition): 매 반복마다 이 조건이 참인지 확인해요. 거짓이 되면 루프를 즉시 종료해요.
  • 후처리(Post): 한 번의 반복이 끝날 때마다 실행돼요. 보통 변수의 값을 증가시키거나 감소시켜요.
💡 알아두기
Go에서는 변수의 범위를 제한하는 것을 선호해요. for 문의 초기화 단계에서 선언된 변수는 해당 루프 안에서만 살아있기 때문에 메모리 관리와 변수 이름 충돌 방지에 매우 유리해요.

상황별 루프 선택 기준

어떤 문법을 쓸지 고민된다면 아래 표를 참고해 보세요. 상황에 맞는 선택이 코드의 가독성을 결정해요.

루프 유형 주요 사용 사례 특징
기본 for 루프 정해진 횟수만큼 반복할 때 인덱스 조절이 자유로움
조건부 for 루프 특정 조건이 유지되는 동안 반복 while 문과 동일한 역할
range 루프 Slice, Array, Map 순회 시 가장 안전하고 간결함
무한 루프 서버 대기, 센서 모니터링 반드시 탈출 조건이 필요함

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

이제 본격적으로 Go의 다양한 반복 패턴을 깊이 있게 살펴볼게요. 각 패턴은 저마다의 용도가 명확하므로, 단순히 암기하기보다 어떤 상황에서 유리한지를 이해하는 것이 핵심이에요.

STEP 1. 전통적인 C 스타일 루프 활용하기

가장 기본이 되는 형태예요. 인덱스 변수를 직접 제어해야 하거나, 증감 폭을 2씩 혹은 5씩 조절해야 하는 특수한 상황에서 유용해요.

for i := 0; i < 10; i++ {
    fmt.Println("현재 인덱스:", i)
}

여기서 i++는 매 반복이 끝날 때마다 i를 1씩 증가시키라는 뜻이에요. 만약 짝수만 출력하고 싶다면 i += 2로 간단히 바꿀 수 있죠. 이 방식은 세밀한 제어가 가능하다는 장점이 있지만, 조건식을 잘못 작성하면 무한 루프에 빠질 위험이 있으니 주의해야 해요.

STEP 2. 조건만으로 제어하는 While 스타일 루프

Go에는 while이라는 키워드가 없지만, for 문에 조건식 하나만 적어주면 똑같이 동작해요. 특정 상태가 변할 때까지 계속 실행해야 하는 로직에 최적화되어 있어요.

count := 1
for count <= 5 {
    fmt.Println("카운트:", count)
    count++
}

이 패턴은 루프 내부에서 어떤 복잡한 계산이 이루어지고, 그 결과에 따라 루프를 계속할지 결정해야 할 때 아주 자연스럽게 읽혀요. 조건식이 거짓이 되는 순간, Go는 아주 깔끔하게 루프를 종료해 줘요.

STEP 3. Slice와 Map을 위한 Range 문법

Go 개발자들이 가장 많이 사용하고, 가장 권장하는 방식이에요. range 키워드를 사용하면 데이터 구조의 인덱스나 값을 아주 쉽게 가져올 수 있어요.

Slice 순회하기

fruits := []string{"사과", "배", "포도"}
for index, value := range fruits {
    fmt.Printf("%d번째 과일: %s\n", index, value)
}

만약 인덱스가 필요 없고 값만 필요하다면, 언더스코어(_)를 사용해 인덱스를 무시할 수 있어요. 이는 Go의 엄격한 변수 사용 규칙을 지키면서 코드를 간결하게 만드는 핵심 기술이에요.

Map 순회하기

scores := map[string]int{"철수": 90, "영희": 85}
for name, score := range scores {
    fmt.Printf("%s의 점수: %d\n", name, score)
}

⚠️ 주의
Map은 저장 순서가 보장되지 않아요. 즉, 루프를 돌릴 때마다 출력되는 순서가 매번 달라질 수 있으니, 순서가 중요한 로직에는 Map을 그대로 사용하면 안 돼요.

STEP 4. 루프의 흐름을 바꾸는 Break와 Continue

반복 도중에 특정 조건에서 탈출하거나, 현재 단계만 건너뛰고 싶을 때가 있죠? 이때 사용하는 것이 바로 제어 키워드예요.

  • break: 루프를 즉시 완전히 종료하고 빠져나가요.
  • continue: 현재 루프의 남은 코드를 실행하지 않고, 다음 반복 단계로 바로 넘어가요.

예를 들어, 리스트에서 특정 숫자를 찾으면 즉시 검색을 중단하고 싶을 때 break를 사용하고, 0이나 음수 같은 잘못된 데이터만 제외하고 싶을 때는 continue를 사용하면 돼요.

STEP 5. 실전 시나리오: 데이터 필터링 및 평균 계산

이 모든 것을 조합해 실제 프로덕션 코드에서 어떻게 쓰이는지 시나리오를 통해 확인해 봐요. 학생들의 성적 데이터에서 60점 미만인 학생을 제외하고 평균 점수를 구하는 로직이에요.

func calculateAverage(scores []int) float64 {
    sum := 0
    count := 0
    for _, score := range scores {
        if score < 60 {
            continue // 낙제 점수는 통계에서 제외해요
        }
        sum += score
        count++
    }
    if count == 0 {
        return 0
    }
    return float64(sum) / float64(count)
}

이 코드에서는 range로 데이터를 훑고, continue로 불필요한 데이터를 걸러낸 뒤, 최종 결과를 계산해요. 실제 업무 환경에서도 이런 식의 필터링 로직은 매우 빈번하게 발생해요.

자주 하는 실수와 해결법

Go의 엄격한 문법 규칙 때문에 초보자들이 흔히 겪는 문제들이 있어요. 에러 메시지를 보고 당황하지 않도록 미리 대비해 두세요.

  • 사용하지 않은 변수 에러 → range 문법에서 인덱스나 값을 선언해 놓고 사용하지 않으면 컴파일 에러가 발생해요. → ✅ 값이 필요 없다면 반드시 _(언더스코어)를 사용해 명시적으로 무시하세요.
  • 무한 루프 발생 → 조건식이 항상 참이거나 증감식이 누락되면 프로그램이 멈추지 않아요. → ✅ 루프 끝에 조건 변화(i++, count–)가 있는지, 혹은 break 조건이 명확한지 확인하세요.
  • Slice 범위 초과(Out of Bounds) → 인덱스를 직접 조절할 때 슬라이스의 길이를 넘어서는 접근을 하면 패닉이 발생해요. → ✅ len(slice)를 사용하여 항상 경계값 안에서만 움직이도록 설계하세요.
  • 반복 중 슬라이스 수정 → 루프를 도는 동안 슬라이스의 요소를 삭제하거나 추가하면 인덱스가 꼬여 예상치 못한 결과가 나와요. → ✅ 수정이 필요하다면 새로운 슬라이스를 만들어 결과를 담는 방식을 권장해요.
  • 타입 불일치 조건식 → 정수형 변수와 실수형 변수를 비교하려고 하면 에러가 나요. → ✅ float64(i)처럼 타입을 명시적으로 변환한 뒤 비교하세요.

자주 묻는 질문

Q. Go에도 while 문이 정말 없나요?

네, 공식적으로는 없어요. 하지만 for condition { ... } 형태를 쓰면 while과 완벽하게 동일하게 작동하므로 걱정할 필요 없어요.

Q. range 루프에서 인덱스와 값을 동시에 가져올 수 있나요?

물론이에요! for i, v := range slice 형식을 사용하면 인덱스(i)와 값(v)을 한 번에 아주 편하게 얻을 수 있어요.

Q. Map을 돌릴 때 순서가 왜 매번 바뀌나요?

Go 설계자들이 맵의 순서에 의존하는 코드를 짜지 못하도록 의도적으로 무작위성을 넣었기 때문이에요. 순서가 중요하다면 데이터를 슬라이스로 옮긴 뒤 순회해야 해요.

Q. 무한 루프를 돌릴 때 CPU 점유율이 너무 높으면 어떡하죠?

실제 서버 환경에서는 루프 안에 time.Sleep()을 넣어 실행 간격을 조절하거나, 채널(Channel)을 이용해 신호가 올 때만 동작하게 만드는 것이 좋아요.

Q. continue를 쓰면 루프 전체가 끝나나요?

아니요, 현재 진행 중인 그 회차의 코드만 건너뛰고 다음 반복으로 바로 넘어가는 거예요. 루프를 끝내고 싶다면 break를 써야 해요.

Go 반복문 정복을 위한 마지막 체크리스트

오늘 배운 내용을 잊지 않도록 핵심만 요약해 드릴게요. 이 리스트를 옆에 두고 코드를 작성해 보세요.

✅ 핵심 요약

  • C 스타일 루프는 세밀한 인덱스 제어가 필요할 때 사용해요.
  • 단순 조건 반복은 for condition {} 형식을 활용해요.
  • Slice나 Map 순회는 range 문법이 가장 안전하고 빨라요.
  • 사용하지 않는 변수는 반드시 _로 처리해야 에러가 안 나요.
  • 루프 제어 흐름을 바꿀 때는 breakcontinue를 구분해서 써요.
  • Map 순회 시 데이터 순서가 보장되지 않는 점을 항상 기억하세요.

이제 여러분은 Go의 유일한 반복문인 for를 자유자재로 다룰 준비가 되었어요. 이론을 아는 것보다 중요한 것은 직접 타이핑하며 에러를 만나보는 것이에요.

오늘 할 일: 방금 배운 range 문법을 사용해 1부터 10까지의 숫자가 담긴 슬라이스를 만들고, 그 합계를 구하는 코드를 직접 짜 보세요.

이번 주 할 일: breakcontinue를 섞어서 조건에 맞는 데이터만 걸러내는 필터링 함수를 만들어 보세요.

학습하다가 막히는 부분이나 이해가 안 되는 코드가 있다면 언제든 댓글로 남겨 주세요. 함께 고민하고 답변해 드릴게요! 함께 성장하는 개발자가 되시길 응원합니다.

함께 읽으면 좋은 글: Go 반복문 for 완벽 가이드

댓글 남기기