Flow control statements: for, if else, switch and defaer
For
for文は;で3つの部分に分かれている。
{初期ステートメント};{条件式};{後処理ステートメント}の形式で書く。
尚、他言語のようにfor文を括弧「()」で括る必要はない、中括弧「{}」は必須。
code:go
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
For continued
for文の初期化ステートメントと後処理ステートメントの記述は任意。
code:go
package main
import "fmt"
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
For is Go's "while"
for文は初期化ステートメントと後処理ステートメントが無い時のみ、;を省略可。
code:go
package main
import "fmt"
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
Forever
ループ条件を省略すれば、無限ループとなる。
code:go
package main
func main() {
for {
}
}
If
for文同様に()は不要で、{}は必要。
code:go
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func main() {
fmt.Println(sqrt(2), sqrt(-4))
}
If with a short statement
if文もfor文同様に条件の前に初期化ステートメントを書ける。
code:go
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
If and else
if文で宣言されて変数は、elseブロックでも使うことができる。
code:go
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
Switch
switch文はif - else文を短く書く方法。
ヒットしたcaseだけが実行される。
code:go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.\n", os)
}
}
Switch evaluation order
switch文のcaseは上から下へ評価される。caseの条件が一致すれば、そこで自動的に停止する。
Switch with no condition
条件のないswitchは、swtich trueと書くことと同じ。
code:go
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
}
Defer
deferステートメントは、deferへ渡した関数の実行を呼び出し元の関数の終わりまで遅延させる。
deferへ渡した関数はすぐに評価されるが、その関数自体はreturnするまで実行されない。
code:go
package main
import "fmt"
func main() {
defer fmt.Println("world") // 最後に実行される
fmt.Println("hello") // 最初に実行される
}
Stacking defers
deferへ渡した関数が複数ある場合、deferへ渡した関数はLIFO(古いデータほど、長く残るデータ格納方式)の順で実行される。
code:go
package main
import "fmt"
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
code:plantext
counting
done
9
8
7
6
5
4
3
2
1
0