Using the tour
A Tour of Goとは
Go言語の最も重要な機能について説明するtourです。
Basics - Flow control statements: for, if, else, switch and defer
For
forループはセミコロン;で3つの部分に分かれています。
- init statement
- condition expression
- post statement
ループは、condition expressionが false となった場合、停止します
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
初期化と後処理ステートメントの記述は任意です。
For is Go's "while"
init statementとpost statementの記述は任意、;も省略できます。
そうすることで、whileは、Goではforだけを使います。
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
Forever
condition expressionも省略すれば、infinite loopになります。
func main() {
for {
}
}
If
ifは、forと同様に、()は不要で、{}は必要です。
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
If with a short statement
if条件の前に、statementを書くことができます。
ここで宣言された変数は、ifのスコープ内だけで有効です。
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
If and else
ifstatementで宣言された変数は、 elseブロック内でも使うことができます。
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)
}
// can't use v here, though
return lim
}
Switch
Goでは選択されたcaseだけを実行し、それに続く全てのcaseは実行されません。
もう一つの違いは
Goのswitchのcaseは定数である必要はなく、
関係する値は整数である必要もないということです。
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の条件が一致すれば、そこで停止(自動的にbreak)します。
switch i {
case 0:
case f():
}
i==0であれば、 case 0でbreakされるためfは呼び出されません。
Switch with no condition
条件のないswitchは、switch trueと書くことと同じです。
このswitchの構造は、if-then-elseのつながりをシンプルに表現できます。
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へ渡した関数の実行を、呼び出し元の関数の終わり(returnする)まで遅延させるものです。
package main
import "fmt"
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
hello
world
Stacking defers
deferへ渡した関数が複数ある場合、その呼び出しはスタックstackされます。
呼び出し元の関数がreturnするとき、渡した関数はlast-in-first-outの順番で実行されます。
package main
import "fmt"
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
counting
done
9
8
7
6
5
4
3
2
1
0