1. if 문
if 문은 해당 조건이 맞으면 { } 블럭안의 내용을 실행한다. Go의 if 조건문은 아래 예제에서 보듯이 조건식을 괄호( )로 둘러 싸지 않아도 된다. 그리고 반드시 조건 블럭 시작 브레이스({)를 if문과 같은 라인에 두어야 한다. 이를 다음 라인에 두게 되면 에러를 발생시킨다.
그리고 한가지 주목할 점은 if 문의 조건식은 반드시 Boolean 식으로 표현되어야 한다는 것이다. 이점은 C/C++ 같은 다른 언어들이 조건식에 1, 0 과 같은 숫자를 쓸 수 있는 것과 대조적이다.
if k == 1 { //같은 라인 println("One") }
if 문은 else if, 혹은 else 문을 함께 가질 수 있다. else if 문은 if 조건문이 거짓일 때 다시 다른 if 조건식을 검사하는 데 사용되며, else 문은 이전의 if 문들이 모두 거짓일 때 실행된다. if 문과 마찬가지로 else if 혹은 else 문의 블럭 시작 브레이스는 같은 라인에 있어야 한다.
if k == 1 { println("One") } else if k == 2 { //같은 라인 println("Two") } else { //같은 라인 println("Other") }
if 문에서 조건식을 사용하기 이전에 간단한 문장(Optional Statement)을 함께 실행할 수 있다. 즉, 아래 예제처럼 val := i*2 라는 문장을 조건식 이전에 실행할 수 있는데, 여기서 주의할 점은 이때 정의된 변수 val는 if문 블럭 (혹은 if-else 블럭 scope) 안에서만 사용할 수 있다는 것이다. 이러한 Optional Statement 표현은 아래의 switch문, for문 등 Go의 여러 문법에서 사용할 수 있다.
if val := i * 2; val < max { println(val) } // 아래 처럼 사용하면 Scope 벗어나 에러 val++
2. Switch 문
여러 값을 비교해야 하는 경우 혹은 다수의 조건식을 체크해야 하는 경우 switch 문을 사용한다. 다른 언어들과 비슷하게 switch 문 뒤에 하나의 변수(혹은 Expression)를 지정하고, case 문에 해당 변수가 가질 수 있는 값들을 지정하여, 각 경우에 다른 문장 블럭들을 실행할 수 있다. 복수개의 case 값들이 있을 경우는 아래 예제에서 보듯이 case 3,4 처럼 콤마를 써서 나열할 수 있다.
package main func main() { var name string var category = 1 switch category { case 1: name = "Paper Book" case 2: name = "eBook" case 3, 4: name = "Blog" default: name = "Other" } println(name) // Expression을 사용한 경우 switch x := category << 2; x - 1 { //... } }
Go의 단순한 switch문 용법은 C++, C#, Java 등의 다른 언어와 비슷하지만, 다음과 같은 것들은 다른 언어와 다른 Go만의 특별한 용법들이다.
switch 뒤에 expression이 없을 수 있음 | 다른 언어는 switch 키워드 뒤에 변수나 expression 반드시 두지만, Go는 이를 쓰지 않아도 된다. 이 경우 Go는 switch expression을 true로 생각하고 첫번째 case문으로 이동하여 검사한다 |
case문에 expression을 쓸 수 있음 | 다른 언어의 case문은 일반적으로 리터럴 값만을 갖지만, Go는 case문에 복잡한 expression을 가질 수 있다 |
No default fall through | 다른 언어의 case문은 break를 쓰지 않는 한 다음 case로 이동하지만, Go는 다음 case로 가지 않는다 |
Type switch | 다른 언어의 switch는 일반적으로 변수의 값을 기준으로 case로 분기하지만, Go는 그 변수의 Type에 따라 case로 분기할 수 있다 |
Go의 switch 문에서 한가지 특징적인 용법은 switch 뒤에 조건변수 혹은 Expression을 적지 않는 용법이다. 이 경우 각 case 조건문들을 순서대로 검사하여 조건에 맞는 경우 해당 case 블럭을 실행하고 switch문을 빠져나온다. 이 용법은 복잡한 if...else if...else if... 문장을 단순화하는데 유용하다.
func grade(score int) { switch { case score >= 90: println("A") case score >= 80: println("B") case score >= 70: println("C") case score >= 60: println("D") default: println("No Hope") } }
Go의 또 다른 용법은 switch 변수의 타입을 검사하는 타입 switch가 있다. 아래 예제는 변수 v의 타입이 int 인지, bool, string 인지를 체크한 후 해당 case 블럭을 실행하는 예이다.
switch v.(type) { case int: println("int") case bool: println("bool") case string: println("string") default: println("unknown") }
C 혹은 C# 과 같은 언어에서 case 문은 case 블럭 마지막에 break 문을 명시하여 switch 문을 빠져나온다. 만약 break 문이 없으면, case 문 밑의 모든 문장들을 실행해 버린다. Go는 case문 마지막에 break 문을 적든 break 문을 생략하든, 항상 break 하여 switch 문을 빠져나온다. 이는 Go 컴파일러가 자동으로 break 문을 각 case문 블럭 마지막에 추가하기 때문이다. Go에서 만약 이러한 디폴트 break 문을 사용하지 않고, C나 C#처럼 계속 밑의 문장들(다음 case문 코드 블럭들)을 실행하게 하려면, fallthrough 문을 명시해 주면 된다. fallthrough 문을 사용한 아래 예제를 실행하면, "2 이하/3 이하/default 도달"을 모두 출력하게 된다. 즉, 일단 case 2 에 도착한 후 fallthrough 가 있으므로, (val 값이 3이 아님에도) case 3의 코드 블럭을 계속 실행하고, case 3에도 fallthrough 가 있으므로 default 블럭을 계속 실행한다.
package main import "fmt" func main() { check(2) } func check(val int) { switch val { case 1: fmt.Println("1 이하") fallthrough case 2: fmt.Println("2 이하") fallthrough case 3: fmt.Println("3 이하") fallthrough default: fmt.Println("default 도달") } }