[IT-정보] Go 반복문 치트시트: 핵심을 한눈에 – 초보자를 위한 필수 문법과 실전 활용 패턴 정리

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

반복문 하나로 모든 것을 해결하는 Go의 단순함

새로운 프로그래밍 언어를 배우다 보면 익숙했던 문법이 보이지 않아 당황할 때가 있어요. 다른 언어에서는 당연하게 사용하던 while이나 do-while 문법을 찾으려고 눈을 비벼봐도 Go(Golang) 코드 어디에도 그 단어는 보이지 않아요. 분명 반복을 해야 하는데 도대체 어디서 시작해야 할지 막막한 기분이 들기도 하죠.

실제로 Go를 처음 접하는 분들이 가장 많이 하는 실수 중 하나가 바로 이 지점이에요. 조건이 참인 동안 계속 실행하는 로직을 짜려고 할 때, Go에는 while이 없다는 사실을 깨닫고 한참을 헤매곤 해요. 하지만 이건 Go가 불친절해서가 아니에요. 오히려 복잡한 문법을 걷어내고 단 하나의 강력한 도구로 모든 상황을 해결하려는 Go만의 철학이 담겨 있는 것이랍니다.

반복문을 잘못 작성하면 프로그램이 멈추지 않고 계속 돌아가는 무한 루프에 빠지거나, 메모리를 과도하게 잡아먹어 시스템 전체를 느리게 만들기도 해요. 특히 대규모 데이터를 처리해야 하는 실무 환경에서는 아주 작은 반복문 실수 하나가 서비스 장애로 이어질 수 있어요. 그래서 Go의 반복문 구조를 정확하게 이해하고, 상황에 맞는 최적의 패턴을 익히는 것이 무엇보다 중요해요.

이 글을 끝까지 읽고 나면 더 이상 while 문법을 찾아 헤맬 필요가 없어요. Go 반복문 치트시트 하나만으로 기초부터 실무 응용까지 완벽하게 정리할 수 있어요. 지금부터 우리가 함께 알아볼 내용은 다음과 같아요.

  • Go의 유일한 반복문, for의 기본 구조와 작동 원리
  • 슬라이스와 맵을 아주 쉽게 다루는 range 활용법
  • 실무에서 즉시 적용 가능한 다양한 반복 패턴
  • 자주 발생하는 실수와 이를 방지하는 디버깅 팁

이제 복잡한 고민은 내려놓고, Go가 제안하는 간결하고 강력한 반복문의 세계로 함께 들어가 보아요.

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

반복문을 본격적으로 다루기 전에, 우리가 어떤 도구를 사용할 수 있는지 먼저 파악해야 해요. Go는 다른 언어와 달리 오직 for 키워드 하나만 사용한다는 점을 머릿속에 꼭 넣어두세요. 대신 이 하나의 도구가 상황에 따라 옷을 갈아입으며 다양한 역할을 수행하게 돼요.

반복문 유형별 특징 비교

어떤 상황에서 어떤 스타일의 반복문을 써야 할지 고민된다면 아래 표를 참고해 보세요. 상황에 맞는 적절한 선택이 코드의 가독성을 결정해요.

유형 주요 특징 추천 상황
C-스타일 for 초기화, 조건식, 증감식을 명시 정해진 횟수만큼 반복할 때
조건식 for 조건식만 사용하여 실행 여부 결정 while 문이 필요할 때
range for 데이터 구조의 요소를 하나씩 순회 슬라이스, 맵, 문자열 순회 시
무한 루프 조건 없이 계속 실행 특정 조건에서 break가 필요할 때

준비해야 할 개념 체크리스트

반복문을 효율적으로 다루기 위해서는 다음 세 가지 개념이 탄탄하게 잡혀 있어야 해요. 이 개념들이 흔들리면 반복문 안에서 논리적 오류를 범하기 쉬워요.

  • 조건식(Condition)의 이해: 반복을 계속할지, 멈출지를 결정하는 불리언(bool) 값의 논리를 명확히 알아야 해요.
  • 증감식(Post statement)의 타이밍: 루프의 한 회차가 끝날 때 변수가 언제 변하는지 그 시점을 정확히 이해해야 해요.
  • 범위(Range)의 개념: 슬라이스나 맵 같은 자료구조가 메모리상에서 어떻게 나열되어 있는지 알아야 효율적인 순회가 가능해요.
💡 알아두기
Go의 for 문은 세미콜론(;)을 사용하여 구성 요소를 구분해요. 만약 세미콜론을 생략하고 조건식만 남긴다면, 그것이 바로 우리가 익숙한 while 문의 역할을 수행하게 된답니다.

이 기초 지식들을 바탕으로 이제 실제 코드로 어떻게 구현하는지 단계별로 살펴볼게요. 준비가 되셨나요?

Go 반복문 실전 활용 가이드

이제 본격적으로 Go 반복문 치트시트의 핵심인 실전 문법을 하나씩 파헤쳐 볼게요. 단순히 코드를 외우는 것이 아니라, 어떤 논리로 코드가 흐르는지 이해하는 것이 목표예요.

STEP 1. 가장 표준적인 C-스타일 for 문법

가장 기본이 되는 형태예요. 정해진 횟수만큼 반복하거나, 인덱스 번호를 직접 제어해야 할 때 사용해요. 구조는 for 초기화; 조건식; 증감식 순서로 이루어져 있어요.

이 방식은 루프가 시작될 때 초기화 문이 딱 한 번 실행되고, 매 반복마다 조건식을 검사해요. 조건이 참이면 실행 블록을 수행한 뒤 증감식을 실행하죠. 매우 직관적이고 강력해요. 예를 들어 1부터 10까지 숫자를 출력하고 싶다면 이 방식을 쓰면 돼요. 하지만 인덱스 변수의 범위를 잘못 설정하면 프로그램이 죽어버릴 수 있으니 주의가 필요해요.

STEP 2. while 문을 대신하는 조건식 기반 반복

Go에는 while이 없지만, 걱정 마세요. for 문에서 초기화와 증감식을 생략하면 우리가 원하는 모든 조건을 다룰 수 있어요. 특정 상태가 변할 때까지 계속 반복해야 하는 상황에서 아주 유용하죠.

예를 들어, 어떤 센서에서 데이터가 들어올 때까지 기다리거나, 특정 조건이 만족될 때까지 계산을 계속해야 하는 경우에 이 방식을 사용해요. 코드가 매우 간결해지기 때문에 가독성 면에서도 훌륭해요. 다만, 조건식이 항상 참이 되지 않도록 내부에서 조건을 변화시키는 코드를 반드시 포함해야 한다는 점을 잊지 마세요.

STEP 3. 데이터 구조를 정복하는 range 활용법

실무에서 가장 많이 쓰게 될 방식이에요. 슬라이스(Slice), 배열(Array), 맵(Map), 채널(Channel) 같은 자료구조의 요소를 하나씩 꺼내올 때 range 키워드를 사용해요. range는 현재 요소의 인덱스(또는 키)와 실제 값을 동시에 제공해 주기 때문에 매우 편리해요.

슬라이스를 순회할 때는 인덱스와 값을 모두 받을 수 있고, 맵을 순회할 때는 키와 값을 쌍으로 가져올 수 있어요. 여기서 한 가지 팁을 드리자면, 만약 인덱스 값이 필요 없다면 언더스코어(_)를 사용하여 빈 블록으로 처리할 수 있어요. 이렇게 하면 불필요한 변수 선언을 줄여 코드가 훨씬 깔끔해져요.

⚠️ 주의
range를 사용할 때 주의할 점이 있어요. range는 반복할 요소의 복사본을 제공한다는 사실이에요. 만약 반복문 안에서 원본 슬라이스의 값을 직접 수정하고 싶다면, 인덱스를 사용하여 원본에 직접 접근해야 해요. 복사본을 수정하는 것은 원본 데이터에 아무런 영향을 주지 않거든요.

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

반복문은 때로 중간에 멈춰야 하거나, 특정 단계만 건너뛰어야 할 때가 있어요. 이때 사용하는 것이 바로 제어문이에요.

  • break: 반복문을 즉시 종료하고 루프 밖으로 탈출해요. 원하는 데이터를 찾았을 때 더 이상 반복할 필요가 없다면 break를 사용해 효율을 높이세요.
  • continue: 현재 진행 중인 반복 회차를 즉시 중단하고, 다음 회차의 조건 검사 단계로 바로 넘어가요. 특정 조건의 데이터를 제외하고 처리하고 싶을 때 매우 유용해요.

STEP 5. 실전 프로젝트 시나리오: 데이터 필터링 및 수정

이론만으로는 부족하죠? 실제 개발 상황에서 마주할 법한 시나리오를 통해 코드가 어떻게 흘러가는지 살펴볼게요. 여러분이 쇼핑몰의 상품 목록(슬라이스)을 관리한다고 가정해 봅시다.

[시나리오] 상품 목록 중에서 가격이 5만 원 이상인 상품들만 골라내어, 그 가격에 10% 할인된 가격을 적용한 새로운 목록을 만들어야 해요.

이 과정에서는 먼저 빈 슬라이스를 하나 준비해요. 그 다음, 기존 상품 슬라이스를 range로 하나씩 순회하면서 조건을 확인해요. 가격이 조건에 맞으면 계산을 수행한 뒤, 새 슬라이스에 append 함수로 추가하는 방식이에요. 이 과정에서 if 문과 for range 문이 유기적으로 결합되어 하나의 비즈니스 로직을 완성하게 돼요. 이러한 패턴은 데이터 가공 작업의 90% 이상을 차지할 만큼 빈번하게 사용된답니다.

또한, 중첩 반복문(Nested Loop)을 사용할 때도 주의가 필요해요. 2차원 배열이나 행렬 데이터를 다룰 때는 반복문 안에 또 다른 반복문이 들어가게 되는데, 이때 안쪽 루프에서 break를 사용하면 안쪽 루프만 종료된다는 점을 명심하세요. 전체 루프를 빠져나가고 싶다면 별도의 플래그 변수를 사용하거나 함수로 로직을 분리하는 것이 현명한 방법이에요.

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

코드를 짜다 보면 누구나 실수를 해요. 특히 반복문은 논리적 흐름이 꼬이기 가장 쉬운 곳이라 더 그래요. 자주 발생하는 패턴들을 정리해 두었으니, 내 코드가 왜 이상하게 작동하는지 궁금할 때 꼭 확인해 보세요.

자주 하는 실수와 해결법

  • 인덱스 범위 초과(Index Out of Range): 슬라이스의 마지막 인덱스를 계산할 때 len(slice)를 그대로 사용하는 경우예요. len은 개수를 반환하므로, 마지막 인덱스는 반드시 len(slice)-1이어야 해요.
    해결법: 가급적 인덱스를 직접 계산하기보다 range를 사용하여 Go가 알아서 범위를 관리하게 하세요.
  • 무한 루프의 늪: 조건식이 항상 참이 되도록 작성하거나, 루프 내부에서 조건을 변화시키는 로직을 누락하는 경우예요.
    해결법: 루프를 돌기 전에 탈출 조건이 명확한지, 조건 변수가 루프 내부에서 반드시 업데이트되는지 검토하세요.
  • range 변수 재사용 문제: Go 버전 1.22 이전 버전에서는 range로 생성된 변수가 매 반복마다 값이 복사되는 것이 아니라 동일한 메모리 주소를 공유했어요. 이로 인해 루프가 끝난 뒤 변수를 확인하면 마지막 값만 남는 현상이 발생하곤 했죠.
    해결법: 최신 Go 버전을 사용하거나, 루프 내부에서 변수를 새로운 변수에 할당하여 사용하세요.
  • 맵 순회 순서의 오해: 맵을 range로 돌릴 때 결과가 매번 다르게 나올 수 있어요. 맵은 순서가 보장되지 않는 자료구조이기 때문이에요.
    해결법: 일정한 순서가 필요하다면 키값들을 슬라이스에 먼저 담아 정렬한 뒤, 그 슬라이스를 바탕으로 맵을 조회하세요.
  • 불필요한 연산 반복: 루프의 조건식 안에 매번 실행할 필요가 없는 무거운 함수를 넣는 경우예요.
    해결법: 반복문 외부에서 미리 값을 계산하여 변수에 저장해 두고, 루프 안에서는 그 변수만 참조하도록 최적화하세요.

자주 묻는 질문

Q. for 문과 range 문 중 어떤 것을 써야 할지 모르겠어요.

데이터의 처음부터 끝까지 모든 요소를 단순히 훑고 지나가야 한다면 range가 가장 빠르고 안전해요. 하지만 특정 인덱스부터 시작하거나, 인덱스를 2씩 건너뛰어야 하는 등 정교한 제어가 필요하다면 for 문을 사용하는 것이 좋아요.

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

가장 깔끔한 방법은 루프 내부에서 특정 조건이 만족될 때 break를 호출하는 것이에요. 만약 중첩된 루프에서 한꺼번에 빠져나가고 싶다면, 루프 로직을 별도의 함수로 감싼 뒤 return을 사용하는 것이 코드가 훨씬 간결해져요.

Q. 맵(Map)을 순회할 때 성능상 이점이 있나요?

맵을 순회하는 것 자체는 슬라이스보다 비용이 더 들 수 있어요. 맵은 해시 테이블 구조이기 때문에 메모리 접근이 연속적이지 않기 때문이죠. 따라서 대량의 데이터를 빠르게 순회해야 한다면 맵보다는 슬라이스를 사용하는 것이 성능 면에서 훨씬 유리해요.

Q. for 문 안에서 슬라이스 요소를 삭제하면 어떻게 되나요?

매우 조심해야 하는 부분이에요! 반복문 중에 슬라이스 요소를 삭제하면 인덱스가 밀리면서 다음 요소를 건너뛰거나 범위를 벗어날 수 있어요. 요소를 삭제해야 한다면, 인덱스를 뒤에서부터 거꾸로 순회하는 패턴을 사용하는 것이 가장 안전해요.

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

지금까지 Go 프로그래밍의 핵심인 반복문 for에 대해 깊이 있게 살펴보았어요. 처음에는 while 문이 없다는 사실이 낯설게 느껴질 수 있지만, 익숙해지면 단 하나의 문법으로 모든 것을 제어할 수 있다는 Go의 단순함이 얼마나 큰 축복인지 깨닫게 될 거예요.

✅ 핵심 요약

  • Go는 오직 for 키워드 하나로 모든 반복을 수행해요.
  • 정교한 제어가 필요하면 C-스타일 for를, 단순 순회는 range를 사용하세요.
  • range는 데이터의 복사본을 제공하므로 원본 수정 시 인덱스 접근이 필요해요.
  • 중첩 루프 탈출이나 복잡한 로직은 함수 분리(return)를 활용하면 깔끔해요.
  • 맵 순회는 순서가 보장되지 않으므로 주의가 필요해요.

반복문은 프로그래밍의 기초 중의 기초이지만, 그 깊이는 끝이 없어요. 오늘 배운 내용을 바탕으로 실제 코드를 직접 작성해 보며 몸으로 익히는 과정이 반드시 필요해요. 단순히 눈으로 읽는 것과 직접 타이핑하며 에러를 마주하는 것은 완전히 다른 차원의 학습이니까요.

오늘 바로 실행해 보세요!

공부한 내용을 잊어버리기 전에 지금 바로 개발 환경을 켜고 아래 과제를 수행해 보세요.

  • 오늘 할 일: 1부터 100까지의 숫자 중 짝수만 출력하는 for 문 작성하기
  • 이번 주 할 일: 슬라이스에 담긴 이름 목록을 range로 순회하며 특정 이름을 찾는 함수 만들기
  • 실행 직전 할 일: 맵(Map)에 데이터를 넣고 range로 순회하며 결과가 매번 어떻게 바뀌는지 직접 눈으로 확인하기

반복문이 익숙해졌다면, 이제 다음 단계인 슬라이스의 내부 구조나 고루틴(Goroutine)을 이용한 병렬 처리로 시야를 넓혀보시는 것을 추천해요. 반복문은 그 거대한 세계로 나아가는 아주 중요한 관문이니까요.

혹시 실습하다가 막히는 부분이 있거나, 이해가 잘 되지 않는 코드가 있다면 언제든 댓글로 남겨 주세요. 제가 확인하는 대로 친절하게 답변해 드릴게요. 여러분의 즐거운 Go 프로그래밍 여정을 응원합니다!

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

댓글 남기기