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
if
statementで宣言された変数は、 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