[学習メモ]A Tour of Go[Flow control statements: for, if, else, switch and defer]
Golangの条件文やループといった基本構文について勉強していきたいと思います。
Golang特有の書き方等ない限りあまり時間をかけずに進んでいきます。
For
for ループはセミコロン ; で3つの部分に分かれる
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
自分はPHPとJavaScriptしか書いたことがないので、ループ条件を()で括らないのは違和感を覚えますね。w
For continued
初期化のステートメントを先に宣言し、forの条件式の中で省略できる
func main() {
sum := 1
for ; sum < 1000; { //省略の場合でも;(セミコロン)は必要
sum += sum
}
fmt.Println(sum)
}
For is Go's "while"
引用 セミコロン(;)を省略することもできます。つまり、C言語などにある while は、Goでは for だけを使います。
package main
import "fmt"
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
普段のコーディングであまりwhile文を使用することがないので、Golangでも自分は使わないかもしれないです。
Forever
無限ループ
package main
import "fmt"
func main() {
for {
fmt.Println("無限ループって怖くね?")
}
}
ループ条件を省略で無限ループになる。怖い。
If
forと同様に条件式を()で囲まない
if x < 0 {
return sqrt(-x) + "i"
}
If with a short statement
forのように条件式の前にステートメントを宣言できる。
ifのスコープ内でのみ有効。
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
バラして書く↓
func pow(x, n, lim float64) float64 {
v := math.Pow(x, n)
if v < lim {
return v
}
return lim
}
If and else
if ステートメントで宣言された変数は、 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
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os { //runtime.GOOS === Linux
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.\n", os)
}
}
caseの最後に必要なbreakは自動的に挿入される。
Switch evaluation order
switch caseは、上から下へcaseを評価します。 caseの条件が一致すれば、そこで停止(自動的にbreak)します。
Switch with no condition
引用
条件のないswitchは、 switch true と書くことと同じです。
このswitchの構造は、長くなりがちな "if-then-else" のつながりをシンプルに表現できます。
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
呼び出した関数が終了する際に実行する処理を記述できる
(Vue.jsのライフサイクルで言うところのdestroyed?)
func main() {
defer fmt.Println("world") //main関数の処理が全て終了後に実行される
fmt.Println("hello")
}
Stacking defers
deferが複数呼ばれているときは、呼び出しはスタックされる。
実行はLIFOの順序で実行される(後入先出し)
package main
import "fmt"
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
[output]
counting
done
9
8
7
6
5
4
3
2
1
0
この章は以上になります。
forやifはややクセがありますが、わかりやすくて良いなと思いました。
deferがどういったところで活躍するのかまだピンときてないので、OSSなどのソースコードを読んで使用されるケースを確認してみます。
この記事が気に入ったらサポートをしてみませんか?