見出し画像

[学習メモ]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などのソースコードを読んで使用されるケースを確認してみます。

この記事が気に入ったらサポートをしてみませんか?