A Tour of Go vol.3
For Continued
初期化と後処理ステートメントは省略可能。
for ; sum < 1000; { sum += sum }
whileはないので繰り返し処理は全てforで記述が統一される。
if
func pow(x, n, lim float64) float64 { if v := math.Pow(x, n); v < lim { return v } return lim }
ifステートメントで宣言した変数はifスコープ内のみ有効なので注意する。
Switch
Switch文ではcaseの条件が一致した時点で自動的にbreakされる。
また条件なしで記述することも可能。
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する)まで遅延させる。
使い所
func main() { file, err := os.Open("hoge.txt") if err != nil { fmt.Println("File open error: ", err) return } buf := make([]byte, 1024) for { n, err := file.Read(buf) if n == 0 { break } if err != nil { fmt.Println("File read error: ", err) return } fmt.Print(buf[:n]) } file.Close() }
上のプログラムの問題はエラーが発生した場合にファイルがCloseされないということ。
こういうところでDeferを使うケースが多いようだ。
func main() { file, err := os.Open("hoge.txt") if err != nil { fmt.Println("File open error: ", err) return } defer file.Close() // <- ここでCloseを遅延実行する buf := make([]byte, 1024) for { // 省略 } }
例外としてos.Exitを使った場合はdeferは実行されない。