2. Flow control statement

For

  • the init statement: 첫 번째 반복 전 실행
  • the condition statement: 모든 반복 전 실행
  • the post statement: 모든 반복 후 실행
  • for statement 에 () 사용 안 한다. 단 {} 은 필수
for i := 0; i < 10: i++ {
    sum += i
}

For is Go's while

  • false가 될 때까지 실행.
for sum < 1000 {
    sum += sum
}

Forever

for {

}

If

  • for와 동일 하게 () 필요 없다. {} 필수
if x < 0 {
    ...
}

If with short statement

  • 짧은 문장을 if 문에 사용 가능
  • 변수의 scope 는 if 블록 안에서만 유효.
if v := get(); v < lim {
    ...
}

If and else

if v < lim {

} else {

}

Switch

  • if else 의 축약형 표현.
  • 매치 되는 첫 번째 문을 실행 시킴
  • 브레이크 문이 없어도 된다. 한 개 실행 후 swich block 을 빠져 나간다.
  • 스위치의 케이스 값이 상수나 int가 아니어도 가능.
switch os := runtime.GOOS; os {
    case "darwin":
        ...
    default:
        ...
}

Switch evaluation order

  • 위에서 아래로 실행 된다.
  • 아래의 예제에서 i == 0 이라면 f() 호출 안 된다.
switch i {
    case 0:
    case f():
}

Switch with nocondition

  • switch true 와 동일 하다.
switch {
    case t.Hour < 12:
        ...
    default:
        ...
}

Defer

  • 감싸고 있는 함수가 리턴 될 때까지 실행이 지연된다.
  • defer 함수에 들어가는 인자는 바로 평가 된다. 하지만 defer된 함수는 감싼 함수가 리턴 될 때 실행
func world() string {
    fmt.Println("world() called")
    return "world"
}
func main() {
    defer fmt.Println(world())

    fmt.Println("hello")
}

// world() called
// hello
// world

Stacking defer

  • 디퍼 함수는 스택처럼 작동 last in first out
func main() {
    fmt.Println("counting")
    // for i := 0; i < 3; i++ {
    //  defer fmt.Println(i)
    // } // 아래와 동일
    defer fmt.Println(0)
    defer fmt.Println(1)
    defer fmt.Println(2)
    fmt.Println("done")
}
// counting
// done
// 2
// 1
// 0

defer, panic, recover detail

  • https://blog.golang.org/defer-panic-and-recover

defer

  • 디퍼문은 디퍼된 함수를 리스트에 집어 넣는 느낌으로 작동.
  • 감싼 함수가 리턴 되면 리스트를 실행.
  • 클린업 action 이 필요 한 경우 사용.
  • 3개 규칙
    • 디퍼 문장이 평가 될때 아규먼트값을 결정.
    • 디퍼 함수는 후입선출 방식으로 실행.
    • 디퍼 함수는 감싼 함수의 아웃 이름 변수를 변경 할 수 있다.

panic

  • 함수 실행을 멈추고 panicking 현상으로 들어감. 디퍼된 함수를 실행 시키고,
  • 스택을 따라 가면 계속 panicking 현상을 발생 시킨다.
  • goroutin 끝에 닿으면 리턴.

recover

  • panicking 을 멈추고 다시 컨트롤을 가져 온다, defer 함수 안에서만 유효.
  • 일반 함수에서는 언제나 nil을 리턴 한다. 아무런 영향이 없다.