제어문

1. if문

제어문 중에 하나로 다른 언어들과 사용목적은 동일하며 if~else if~else를 똑같이 지원한다.

◾ 선언 방법

score := 56

if score > 80 {
  fmt.Println("A")
} else if(score > 50) {   //소괄호로 감쌌지만 not Error
  fmt.Println("B")
} else {
  fmt.Println("C")
}

if true {
  fmt.Println("true") //조건이 bool이면 success
}

if 1 {
  fmt.Println("true")  //bool이 아니면 error
}

Java나 c처럼 ()로 조건문을 감싸지 않고 바로 조건문을 작성하면 되고 Java처럼 조건문은 bool타입을 반환해야 한다. C/C++처럼 0이 false, 1이상이 true로 인식되지 않는다.

소괄호로 감싸지 않는게 기본 문법이지만 감싼다고 해서 에러가 발생하지는 않는다.


◾ Error 발생하는 경우

//1
if (socre > 80) fmt.Println("A")

//2
if score > 80
{
  fmt.Println("A")
}

//3
if score > 80{
  fmt.Println("A")
}
else{
  fmt.Println("B")
}

Go는 지금까지 설명한것처럼 특정 문법 형식을 강제하는 언어인데 조건문도 그 예외는 아니다.

첫번째로 대부분의 언어에서 조건문 내부가 한줄이라면 중괄호를 생략해서 표현하기도 하는데 go는 무조건 중괄호로 묶어야 한다. 두번째는 조건문 키워드 옆에 바로 중괄호가 시작되어야 한다. 위의 예제처럼 다음줄에서 시작한다면 error를 발생한다.

마지막으로는 if~else if~else를 작성할때 else ifelse는 위의 조건이 끝나는 중괄호 바로 옆에 작성해야 하기 때문에 다음 문단에서 시작된다면 에러를 발생시킨다.



switch문

◾ 선언 방법

const (
  apple = iota
  banana
  orange
  strawberry
  grape
)

var name string
var fruit = apple

//case 1
switch fruit {
case apple:
  name = "Apple"
case banana:
  name = "Banana"
case orange, strawberry:
  name = "Orange and StrawBerry"
default:
  name = "Other"
}

fmt.println(name)

//case 2. Expression사용
switch x:= fruit-1; x+1 {
	case apple:
		name = "Apple"
	case banana:
		name = "Banana"
	case orange, strawberry:
		name = "Orange and StrawBerry"
	default:
		name = "Other"
	}

기본적으로 switch키워드 뒤에 변수를 선언하고 다른 언어들과 비슷한 문법으로 switch를 사용할 수 있지만 별도의 expression을 사용할경우에는 세미콜론(;)뒤에 case로 사용될 값을 정의해주면 된다.


◾ 특징

1. switch뒤에 변수가 없어도 된다.

score := 67

switch {
	case score >= 80:
		fmt.Println("A")
	case score >= 60:
		fmt.Println("A")
	case score >= 40:
		fmt.Println("C")
	default:
		fmt.Println("F")
	}

다른 언어는 switch 키워드 뒤에 변수나 expression을 선언하지만 Go는 선언하지 않아도 되며 선언하지않으면 true로 생각해 첫번째 case문으로 이동을 한다. 이때 case 조건으로는 bool만 올 수 있다.


2. case에 조건문 표현 가능

위의 예시처럼 case에 특정 값(리터럴)을 표현하는 것이 아니라 조건문을 선언할 수 있다. 조건문으로 case를 표시할 경우에는 리터럴값과 혼용해서 사용할 수 없다.

score := 50

switch score{
case 67 :
  fmt.Println(67)
case score >= 80:   //error
  fmt.Println("A")
default:
  fmt.Println("F")
}


3. case에 변수 타입 가능

var val interface{} = 15

	switch val.(type) {
	case int:
		println("int")
	case bool:
		println("bool")
	case string:
		println("string")
	default:
		println("unknown")
	}

	fmt.Println(val)    //int

말그대로 case에 변수타입으로 분기할 수 있다. 이는 .(type)을 변수로 주어지면 사용할 수 있는데 이는 동적 타입을 갖는 인터페이스의 경우 인터페이스가 가지고 있는 실제 값에 접근하게 해주는 type assertion을 이용한 것이다.


4. break생략 가능

기존의 다른언어들은 case가 끝날때 break를 생략하게되면 다음 case가 이어서 실행되는데 Go는 break를 사용하지 않아도 한 case를 실행하면 자동으로 종료 된다.

score := 67

switch {
	case score >= 80:
		fmt.Println("A")
    fallthrough
	case score >= 60:
		fmt.Println("A")
    fallthrough
	case score >= 40:
		fmt.Println("C")
    fallthrough
	default:
		fmt.Println("F")
	}

만약에 다음 case도 이어서 실행을 하고 싶다면 fallthrough을 명시해주면 이어서 실행이 가능하다.





Reference

『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트