고 기초 #3 제어 흐름 — if, for, switch
#2 변수, 타입, 상수에서 값을 다루는 도구를 봤습니다. 이번엔 — 그 값들로 분기와 반복을 만드는 차례입니다.
if / else if / else
#
조건 분기. 다른 언어와 거의 비슷하지만 소괄호 없음이 특징입니다.
score := 85
if score >= 90 {
fmt.Println("A")
} else if score >= 80 {
fmt.Println("B")
} else {
fmt.Println("C")
}if (조건)이 아니라 if 조건입니다. C/Java 스타일에서 오면 처음에 어색하지만 빠르게 익숙해집니다.
짧은 선언 (short statement) #
조건 안에서 변수 하나를 선언하고 즉시 사용할 수 있습니다. Go에서 매우 자주 만나는 패턴.
if v, ok := lookup(key); ok {
fmt.Println("찾음:", v)
} else {
fmt.Println("없음")
}v, ok := lookup(key)가 if 안에서 일어나고, v와 ok는 if/else 블록에서만 보입니다. 블록을 빠져나가면 사라집니다.
이 패턴이 Go 코드 도처에 등장합니다. 에러 검사(#4)의 표준 모양이기도 합니다.
조건은 bool만
#
x := 5
// if x { ... } ✗ x는 int
if x > 0 { ... } // OK
// if v := lookup(); v { ... } ✗ v가 bool이 아니면 안 됨자바스크립트의 truthy/falsy 같은 자동 변환이 없습니다. 명시적인 조건만 받습니다.
for — 유일한 반복문
#
Go에는 while이 없습니다. for 하나로 모든 반복을 표현합니다.
1) 고전 for — 세 부분 #
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// 0, 1, 2, 3, 4C/Java와 같은 모양입니다. 초기화 ; 조건 ; 매 반복 후 실행 순서입니다.
2) while처럼 — 조건만 #
n := 0
for n < 5 {
fmt.Println(n)
n++
}세 부분 중 조건만 있는 형태. 다른 언어의 while과 같은 의미입니다.
3) 무한 루프 — 조건도 없음 #
for {
// ...
if shouldStop() {
break
}
}for { }가 무한 루프. while (true)와 같은 의미입니다.
4) for range — 컬렉션 순회
#
fruits := []string{"사과", "바나나", "포도"}
for i, fruit := range fruits {
fmt.Println(i, fruit)
}
// 0 사과
// 1 바나나
// 2 포도ages := map[string]int{
"커티스": 30,
"앨리스": 25,
}
for name, age := range ages {
fmt.Println(name, age)
}for i, r := range "안녕" {
fmt.Printf("%d: %c\n", i, r)
}
// 0: 안
// 3: 녕 (UTF-8 바이트 인덱스)for range는 매우 강력합니다. 인덱스/키만 필요하면 두 번째 변수를 빼고, 값만 필요하면 첫 번째를 _로 무시.
for i := range fruits { // 인덱스만
fmt.Println(i)
}
for _, fruit := range fruits { // 값만
fmt.Println(fruit)
}break와 continue
#
루프 흐름 제어.
for i := 0; i < 10; i++ {
if i == 5 {
break // 루프 빠져나가기
}
if i%2 == 0 {
continue // 다음 반복으로
}
fmt.Println(i)
}
// 1, 3라벨로 중첩 루프 제어 #
여러 겹 중첩 루프에서 한 번에 빠져나가고 싶을 때 사용합니다.
outer:
for i := 0; i < 5; i++ {
for j := 0; j < 5; j++ {
if i*j > 6 {
break outer // outer 라벨까지 한 번에 break
}
}
}자주 쓰진 않지만 깊은 중첩에서 깔끔합니다.
switch — Go의 가장 큰 차이
#
Go의 switch는 자동으로 fallthrough 하지 않습니다. C/Java와 정반대.
day := "mon"
switch day {
case "mon", "tue", "wed", "thu", "fri":
fmt.Println("평일")
case "sat", "sun":
fmt.Println("주말")
default:
fmt.Println("?")
}매 case 끝에 자동 break. 옛 C처럼 break를 적을 필요가 없습니다. 여러 값을 한 case에 콤마로 묶을 수도 있습니다.
강제 fallthrough #
정말로 다음 case로 흘려보내고 싶으면 fallthrough 키워드.
n := 1
switch n {
case 1:
fmt.Println("one")
fallthrough
case 2:
fmt.Println("two")
}
// one
// two거의 안 씁니다. 의도가 분명할 때만.
조건식 switch — if/else의 짧은 형태 #
표현식 없는 switch는 if/else 사슬을 짧게 만듭니다.
score := 85
switch {
case score >= 90:
fmt.Println("A")
case score >= 80:
fmt.Println("B")
case score >= 70:
fmt.Println("C")
default:
fmt.Println("F")
}각 case가 bool 표현식. 길어지는 if/else if보다 보기 좋을 때가 많습니다.
switch + 짧은 선언 #
if처럼 switch도 짧은 선언을 허용합니다.
switch v := getValue(); {
case v > 100:
fmt.Println("크다")
case v > 0:
fmt.Println("양수")
default:
fmt.Println("0이하")
}타입 switch — interface 분기 #
중급 #1 인터페이스에서 본격적으로 다루지만, switch가 타입 검사에도 쓰입니다.
func describe(i interface{}) {
switch v := i.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
case bool:
fmt.Println("bool:", v)
default:
fmt.Println("unknown")
}
}i.(type)이라는 특별한 문법. 인터페이스가 어떤 구체 타입을 들고 있는지에 따라 분기합니다.
goto — 거의 안 씀
#
Go에 goto가 있긴 하지만 거의 안 씁니다. 정말 특수한 경우(중첩에서 빠져나가기, 정리 코드)에서만 만납니다.
짧은 if의 함정 — 중괄호 필수 #
자바스크립트와 달리 Go는 중괄호가 항상 필수입니다.
// if condition doSomething() ✗ 컴파일 에러
if condition {
doSomething()
}이 디자인 덕분에 자바스크립트의 “들여쓰기 가짜 if” 같은 함정이 아예 없습니다.
자주 쓰는 패턴들 #
1) 에러 검사 #
if err != nil 패턴이 Go 코드에서 가장 자주 보이는 모양 중 하나입니다.
file, err := os.Open("data.txt")
if err != nil {
return err
}
defer file.Close()
// ... 정상 처리#4에서 자세히 다룹니다.
2) 키 존재 확인 #
ages := map[string]int{"커티스": 30}
if age, ok := ages["커티스"]; ok {
fmt.Println(age)
}map[키]는 두 값을 반환할 수 있습니다 — 값과 존재 여부 ok. 이 짧은 선언 패턴이 표준입니다.
3) early return #
깊은 if/else보다 일찍 return 하는 패턴.
func process(s string) error {
if s == "" {
return fmt.Errorf("빈 문자열")
}
if len(s) > 100 {
return fmt.Errorf("너무 긴 문자열")
}
// 본 로직 — 들여쓰기 한 단계만
return nil
}자바스크립트 #4 함수에서 본 패턴과 같습니다. Go에서도 권장됩니다.
마무리 #
이번 글에서 정리한 내용:
if 조건 { }— 소괄호 없음, 중괄호 필수- 짧은 선언 —
if v, ok := ...; ok { }가 자주 등장 - 조건은 bool만 — truthy/falsy 자동 변환 없음
for가 유일한 반복문 — while/do-while 없음- 4가지 형태 — 고전, 조건만, 무한, range
for range로 슬라이스/맵/문자열 순회 (문자열은 rune)switch는 자동 break — fallthrough 명시- 조건식 switch로 if/else 사슬 정리
i.(type)으로 타입 switch (미리보기)
다음 글(#4 함수, 다중 반환, error 타입)에서는 Go의 함수 — 정의 방식, 다중 반환, 그리고 가장 중요한 에러 처리 패턴을 다룹니다.