Flow control statement
For > the only one looping construct
The basic for loop has three components separated by semicolons:
- the init statement: executed before the first iteration (optional)
- the condition expression: evaluated before every iteration
- 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 | for sum < 1000 { |
infinite loop > no condition
1 | for{ |
break
1 | i:=0 |
if
1 | if [short statement;](optional) condition{ |
If with a short statement
Like for, the if statement can start with a short statement to execute before the condition.
1 | if a := 1; b > 10{ |
If and else
Variables declared inside an if short statement are also available inside any of the else blocks.
1 | if v := math.Pow(x, 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 | switch init expression; condition{ |
Switch evaluation order
Switch cases evaluate cases from top to bottom, stopping when a case succeeds.
1 | // does not call f if i == 0 |
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 | switch { |
fallthrough
1 | switch init expression; 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 | func main(){ |
The deferred call’s arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.
1 | func a() { |
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 | for i := 0; i < 10; i++ { |
To learn more about defer statements read this blog post.
The behavior of defer statements is straightforward and predictable. There are three simple rules:
- 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.
- Deferred function calls are executed in Last In First Out order after the surrounding function returns.
1 | // This function prints "3210": |
- 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 | func c() (i int) { |
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.