[IT-정보] Go 반복문 치트시트: 핵심을 한눈에 – 입문 개발자를 위한 실전 문법과 코드 패턴 정리

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

반복문 for, 왜 Go에서는 하나뿐일까요?

파이썬을 쓰다가 Go로 넘어오면 가장 먼저 당황하는 순간이 있어요. 분명 반복문이 필요한데 while 문도 없고, do-while 문도 보이지 않기 때문이에요. 키워드를 아무리 찾아봐도 오직 for 하나뿐이라서 처음에는 당황스러울 수 있어요.

하지만 이건 Go 언어가 지향하는 철학인 단순함을 가장 잘 보여주는 대목이에요. Go 설계자들은 복잡한 키워드를 늘리는 대신, 하나의 강력한 도구인 for를 상황에 맞춰 변형해 사용하는 방식을 선택했어요. 이 규칙에 익숙해지면 코드가 훨씬 간결해지고 읽기 쉬워지는 경험을 하게 돼요.

반복문을 잘못 사용하면 프로그램이 멈추지 않는 무한 루프에 빠지거나, 존재하지 않는 메모리 공간에 접근하려다 프로그램이 즉시 종료되는 에러를 마주하기도 해요. 특히 입문 단계에서는 슬라이스의 길이를 잘못 계산하거나 range 사용법을 헷갈려 시간을 허비하는 경우가 많아요.

이 글을 끝까지 읽고 나면 복잡한 로직도 깔끔한 Go 스타일의 반복문으로 구현할 수 있게 돼요. 다음 내용들을 핵심적으로 다룰 예정이에요.

  • 표준적인 C 스타일의 for 문 사용법
  • Go만의 강력한 range를 이용한 컬렉션 순회
  • 무한 루프와 조건부 루프 구현 방법
  • 실전에서 즉시 활용 가능한 코드 패턴과 주의사항

반복문을 시작하기 전 반드시 알아야 할 기초

Go의 반복문을 제대로 다루려면 단순히 문법을 외우는 것보다, 제어 흐름이 어떻게 작동하는지 이해하는 게 더 중요해요. 다른 언어에서 보던 while 문이나 foreach 문이 모두 for라는 하나의 틀 안에서 어떻게 변신하는지 그 원리를 파악해야 해요.

반복문을 작성할 때는 항상 세 가지 요소를 머릿속에 그려보세요. 시작할 때 초기화할 변수, 언제까지 반복할지 결정하는 조건, 그리고 한 번의 루프가 끝날 때마다 수행할 증감식이에요. Go는 이 세 가지를 아주 유연하게 배치할 수 있도록 설계되었어요.

💡 알아두기
Go의 for 문은 매우 다재다능해서, 작성 방식에 따라 기능이 완전히 달라져요. 문법이 단순한 만큼 상황에 맞는 적절한 패턴을 선택하는 안목이 필요해요.

본격적으로 코드를 짜기 전에, 상황에 따라 어떤 형태의 반복문을 선택해야 효율적인지 비교해 보았어요. 아래 표를 통해 기준을 잡아보세요.

반복 유형 주요 특징 추천 상황
표준형 for 초기값, 조건, 증감식을 모두 명시 횟수가 정해진 숫자를 셀 때
조건형 for 조건식만 남겨둠 (while 역할) 특정 상태가 될 때까지 반복할 때
range형 for 슬라이스, 맵 등의 요소를 순회 데이터 집합을 하나씩 꺼낼 때
무한 루프 조건식 없이 for만 작성 서버 대기나 채널 감시 시

이 기준을 바탕으로 실제 코드를 어떻게 작성하는지 단계별로 살펴볼게요. 단순히 문법을 나열하는 것이 아니라, 실무에서 어떤 로직을 구현할 때 이 패턴이 쓰이는지 구체적으로 설명해 드릴게요.

실전 Go 반복문 패턴 완벽 가이드

이제 본격적으로 Go 반복문 치트시트의 핵심인 실전 패턴을 살펴볼게요. 각 단계는 가장 자주 쓰이는 순서대로 구성했어요. 코드를 눈으로만 보지 말고, 직접 타이핑하며 흐름을 느껴보세요.

STEP 1. 가장 기본적인 C 스타일 for 문

가장 정석적인 방법이에요. 횟수를 정확히 제어해야 하거나, 인덱스 값을 직접 조절하며 건너뛰어야 할 때 유용해요. 구조는 for [초기화]; [조건]; [증감식] 순서로 이루어져요.

// 1부터 10까지 출력하는 기본 예제
for i := 1; i <= 10; i++ {
    fmt.Println(i)
}

여기서 주의할 점은 변수 i의 생명주기예요. for 문 안에서 선언된 i는 루프가 끝나면 메모리에서 사라져요. 루프 외부에서도 이 값을 쓰고 싶다면 for 문 밖에서 미리 선언해야 한다는 점을 잊지 마세요. 또한, 증감식 위치를 잘못 지정하면 의도치 않은 무한 루프에 빠질 수 있으니 세미콜론(;) 위치를 잘 확인해야 해요.

STEP 2. while 문을 대신하는 조건식 루프

Go에는 while 키워드가 없어요. 대신 for 문에서 초기화와 증감식을 생략하면 while 문과 똑같이 동작해요. 특정 조건이 만족되는 동안 계속 실행하고 싶을 때 아주 효과적이에요.

// 특정 조건이 될 때까지 반복 (while 역할)
count := 0
for count < 5 {
    fmt.Println("현재 카운트:", count)
    count++
}

이 패턴은 주로 데이터베이스에서 데이터를 가져오거나, 채널(Channel)로부터 값이 들어올 때까지 기다리는 로직에서 정말 많이 사용돼요. 조건식이 false가 되는 순간 즉시 루프를 빠져나온다는 점만 기억하면 돼요.

STEP 3. 컬렉션을 위한 range 루프 활용

슬라이스(Slice)나 맵(Map) 같은 데이터 집합을 다룰 때는 range를 쓰는 게 훨씬 안전하고 깔끔해요. 인덱스를 직접 계산하다가 실수할 확률을 획기적으로 줄여주거든요.

// 슬라이스 순회 예제
names := []string{"철수", "영희", "민수"}
for index, name := range names {
    fmt.Printf("%d번 손님: %s\n", index, name)
}

// 인덱스가 필요 없을 때는 빈 식별자(_) 사용
for _, name := range names {
    fmt.Println("이름:", name)
}

여기서 아주 중요한 팁이 있어요. 만약 range를 통해 받은 값을 루프 안에서 사용하지 않으면서도 변수 이름을 적어주면, Go 컴파일러는 "unused variable" 에러를 내뱉으며 빌드를 거부해요. 이때는 반드시 _(blank identifier)를 사용해서 "이 값은 안 쓸 거야"라고 명시해 주어야 해요. 맵(Map)을 순회할 때는 key, value 순서로 값을 가져온다는 점도 꼭 기억해 두세요.

STEP 4. 제어 흐름 조절하기: break와 continue

루프를 도는 도중 특정 상황에서 멈추거나, 이번 차례만 건너뛰고 싶을 때가 있죠? 이때 사용하는 것이 breakcontinue예요. 이 두 키워드만 잘 써도 복잡한 조건문을 대폭 줄일 수 있어요.

// continue와 break 실전 예제
for i := 1; i <= 10; i++ {
    if i%2 == 0 {
        continue // 짝수일 때는 아래 코드를 실행하지 않고 다음 루프로 건너뜀
    }
    if i > 7 {
        break // 7보다 커지면 루프를 완전히 종료
    }
    fmt.Println("홀수 발견:", i)
}

continue는 현재의 반복 회차를 생략하고 곧바로 다음 증감식 단계로 넘어가고, break는 루프 전체를 즉시 탈출해요. 조건이 까다로워질수록 이 두 키워드의 조합이 코드를 얼마나 간결하게 만드는지 체감하게 될 거예요.

STEP 5. 중첩 루프 탈출을 위한 레이블(Label) 사용

루프 안에 루프가 있는 중첩 구조에서는 break 하나만으로는 바깥쪽 루프까지 한 번에 나갈 수 없어요. 이때 Go의 독특한 기능인 레이블을 사용하면 마법처럼 해결돼요.

// 레이블을 이용한 중첩 루프 탈출
OuterLoop:
for i := 1; i <= 3; i++ {
    for j := 1; j <= 3; j++ {
        if i == 2 && j == 2 {
            fmt.Println("조건 충족! 모든 루프 탈출!")
            break OuterLoop // OuterLoop라고 이름 붙인 바깥 루프를 종료
        }
        fmt.Printf("i: %d, j: %d\n", i, j)
    }
}

보통은 중첩 루프를 피하는 것이 좋은 설계이지만, 알고리즘을 구현하거나 복잡한 데이터를 처리하다 보면 불가피하게 레이블이 필요할 때가 있어요. break 레이블명 형식을 사용하여 흐름을 제어해 보세요.

💡 알아두기
중첩 루프에서 레이블을 남발하면 코드가 복잡해질 수 있어요. 레이블은 정말 꼭 필요한 상황에서만 사용하여 가독성을 유지하는 것이 고수의 비결이에요.

자주 하는 실수와 해결법

실전 개발 중에 마주칠 수 있는 뼈아픈 실수들을 정리했어요. 미리 익혀두면 디버깅 시간을 엄청나게 아끼는 데 도움이 될 거예요.

  • 인덱스 범위 초과(Out of Bounds)
    왜 발생할까요? 슬라이스의 길이를 계산할 때 i <= len(slice)처럼 등호를 잘못 넣었을 때 발생해요. 인덱스는 0부터 시작하므로 마지막 인덱스는 len(slice)-1이에요.
    해결법: 항상 i < len(slice)를 사용하거나, 가급적 range를 사용하여 직접 인덱스를 계산하지 마세요.
  • 무한 루프(Infinite Loop)
    왜 발생할까요? 조건식이 항상 true이거나, 증감식이 누락되어 조건이 변하지 않을 때 생겨요.
    해결법: 루프 내부에 조건을 변화시키는 코드가 확실히 있는지 확인하고, 테스트 시에는 반드시 탈출 조건이 작동하는지 체크하세요.
  • 클로저에서의 반복 변수 캡처 문제
    왜 발생할까요? Go의 루프 변수는 재사용되는 특성이 있어서, 루프 안에서 고루틴(Goroutine)을 생성할 때 모든 고루틴이 마지막 인덱스 값만 참조하는 현상이 생겨요.
    해결법: 루프 안에서 변수를 하나 더 선언하여 값을 복사해 사용하거나, Go 1.22 버전 이후의 최신 문법을 사용하세요.
  • 맵(Map) 순회 시 순서 혼란
    왜 발생할까요? Go의 맵은 내부적으로 순서가 보장되지 않아요. 루프를 돌 때마다 결과가 달라질 수 있어요.
    해결법: 순서가 중요하다면 키(Key)들을 별도의 슬라이스에 담아 정렬한 뒤, 그 슬라이스를 기준으로 맵을 순회하세요.
  • 슬라이스 수정 중 순회
    왜 발생할까요? range로 순회하는 도중에 원본 슬라이스의 요소를 삭제하거나 추가하면 예상치 못한 결과가 나와요.
    해결법: 요소를 삭제해야 한다면 역순(뒤에서부터 앞으로)으로 루프를 돌거나, 별도의 슬라이스에 결과를 담아두세요.

자주 묻는 질문

Q. Go에는 정말 while 문이 아예 없나요?

네, 맞아요. Go는 언어의 단순성을 위해 for 하나로 모든 반복 기능을 통합했어요. for condition { ... } 형태로 쓰면 우리가 아는 while 문과 완전히 똑같이 작동하니 걱정 마세요.

Q. range를 쓸 때 index를 하나도 안 쓰고 싶으면 어떻게 하나요?

for _, value := range collection { ... } 처럼 언더스코어(_)를 사용하면 돼요. Go에서는 사용하지 않는 변수를 허용하지 않기 때문에 이 문법이 필수적이에요.

Q. 무한 루프를 안전하게 멈추는 가장 좋은 방법은 무엇인가요?

단순히 break를 쓸 수도 있지만, 채널을 사용하여 외부에서 신호를 보내 종료하는 방식이 Go다운 방식이에요. Context 패키지를 활용해 루프를 종료하는 패턴을 익혀두면 훨씬 전문적인 코드를 짤 수 있어요.

Q. for 루프 안에서 return을 쓰면 어떻게 되나요?

return은 루프만 나가는 게 아니라, 해당 루프를 포함하고 있는 함수 자체를 즉시 종료하고 값을 반환해요. 루프만 빠져나가고 싶다면 반드시 break를 사용해야 해요.

반복문 마스터를 위한 마무리

오늘 우리는 Go의 유일한 반복문인 for를 통해 다양한 상황을 해결하는 방법을 배웠어요. 처음에는 while이 없어서 어색할 수 있지만, 익숙해지면 하나의 키워드로 모든 것을 처리하는 Go의 간결함에 매료될 거예요.

✅ 핵심 요약

  • 정해진 횟수는 표준형 for i := 0; i < n; i++ 패턴을 사용하세요.
  • 조건에 따른 반복은 for condition { ... } 형식을 활용하세요.
  • 컬렉션 순회 시에는 안전한 range 사용이 최선이에요.
  • 사용하지 않는 값은 반드시 _로 처리해야 에러가 나지 않아요.
  • 중첩 루프 탈출이 필요할 땐 레이블(Label)을 기억하세요.
  • 맵 순회는 순서가 보장되지 않는다는 점을 항상 염두에 두세요.

이제 이론은 충분해요. 다음 단계로 넘어가기 위해 오늘 당장 이것들을 실천해 보세요.

  • 오늘 할 일: 지금 바로 IDE를 켜고 슬라이스 3개를 만들어 range로 출력하는 코드를 짜보세요.
  • 이번 주 할 일: breakcontinue를 섞어 복잡한 조건문 없이 루프를 제어하는 연습을 해보세요.
  • 실행 직전 할 일: range를 쓸 때 언더스코어(_)를 적절히 사용하는 법을 손에 익히세요.

Go 프로그래밍을 공부하다가 막히는 부분이 있다면 언제든 댓글로 남겨 주세요. 함께 고민하고 답변해 드릴게요!

더 깊이 있는 Go 언어 학습을 원하신다면 Go 반복문 완전 정복 가이드 글도 함께 읽어 보시기를 추천해요.

댓글 남기기