0%

A Tour Of Go/ Flow control statement

Flow control statement

For > the only one looping construct

The basic for loop has three components separated by semicolons:

  1. the init statement: executed before the first iteration (optional)
  2. the condition expression: evaluated before every iteration
  3. the post statement: executed at the end of every iteration(optional)

The init statement will often be a short variable declaration, and the variables declared there are visible only in the scope of the for statement.

Note:
there are no parentheses surrounding the three components of the for statement
the braces { } are always required.

for(while) > only condition

1
2
3
for sum < 1000 {
sum += sum
}

infinite loop > no condition

1
2
3
for{
// ...
}

break

1
2
3
4
5
6
7
i:=0
for{
i++
if i>10{
break
}
}

if

1
2
3
if [short statement;](optional) condition{
// short statement and here are in the same scope
}

If with a short statement

Like for, the if statement can start with a short statement to execute before the condition.

1
2
3
if a := 1; b > 10{
fmt.Print(a, b)
}

If and else

Variables declared inside an if short statement are also available inside any of the else blocks.

1
2
3
4
5
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}

Switch

It runs the first case whose value is equal to the condition expression.

  • Go only runs the selected case, not all the cases that follow.
  • no need to use break statement
  • Go’s switch cases need not be constants, and the values involved need not be integers.
1
2
3
4
5
6
7
8
switch init expression; condition{
case A:
AAA
case B:
BBB
default:
XXX
}

Switch evaluation order

Switch cases evaluate cases from top to bottom, stopping when a case succeeds.

1
2
3
4
5
// does not call f if i == 0
switch i {
case 0:
case f():
}

Switch with no condition

Switch without a condition is the same as switch true.

This construct can be a clean way to write long if-then-else chains.

1
2
3
4
5
6
7
8
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}

fallthrough

1
2
3
4
5
6
7
8
9
10
11
switch init expression; os{
case 1:
fmt.Println("OS X.")
fallthrough // 執行下一個 case
case f():
fmt.Println("Linux.")
fallthrough
default:
// plan9, windows...
fmt.Printf("%s.", os)
}

Defer

A defer statement defers the execution of a function until the surrounding function returns.

Q: what does surrounding function return mean ?
A: see some example will be more easy to understand.
when func2 finished and prepare to return

1
2
3
4
func main(){
defer func1() // pause execution
func2()
}

The deferred call’s arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.

1
2
3
4
5
6
7
8
9
10
func a() {
i := 0
defer fmt.Println(i)
i++
fmt.Println(i)
return
}
// output:
1
0

Stacking defers

Deferred function calls are pushed onto a stack.
When a function returns, its deferred calls are executed in last-in-first-out order.

1
2
3
4
for i := 0; i < 10; i++ {
defer fmt.Print(i)
}
// output: 9876....1

To learn more about defer statements read this blog post.

The behavior of defer statements is straightforward and predictable. There are three simple rules:

  1. A deferred function’s arguments are evaluated when the defer statement is evaluated.

感覺有點像是閉包

In this example, the expression “i” is evaluated when the Println call is deferred. The deferred call will print “0” after the function returns.

  1. Deferred function calls are executed in Last In First Out order after the surrounding function returns.
1
2
3
4
5
6
7
// This function prints "3210":

func b() {
for i := 0; i < 4; i++ {
defer fmt.Print(i)
}
}
  1. Deferred functions may read and assign to the returning function’s named return values.

In this example, a deferred function increments the return value i after the surrounding function returns. Thus, this function returns 2:

1
2
3
4
func c() (i int) {
defer func() { i++ }()
return 1
}

This is convenient for modifying the error > 我目前看不出來

Defer 機制解說:

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

In summary, the defer statement (with or without panic and recover) provides an unusual and powerful mechanism for control flow.