ゆるりのこと。

文系営業マンから新米データサイエンティストしています。

A Tour of Goのざっくりまとめ② <Flow control statements: for, if, else, switch and defer編>

こちらの続編です。

mattsun-plapla.hatenablog.com

A Tour of Goはこちら。あそべます。Playaround最高。

go-tour-jp.appspot.com


今回はfor, if文などについてです。

forループ

for 文は下記の3つのパートで分解できる。

https://go-tour-jp.appspot.com/flowcontrol/1


この中で、条件式パートがないと、無限ループが発生してしまう。

package main

import (
	"fmt"
)

func main() {
	sum := 0 // 初期値0のsum変数(int型) 
	// i変数を初期化, i < 10までループ処理をおこなう, 最後にi+1をおこなう
        for i := 1; i < 10; i++ {
		sum += i
	}
	fmt.Println(sum) // 45

       // 初期化と後処理を省略したVer. ";"も省略可
       for sum < 10 {
		sum++
       }
       fmt.Println(sum) // 10
}

Goにはwhile文がないため、代わりに2つ目のような書き方をするようです。

if-else

if文はこんなかんじ。

// 基本構文
if condition {
	// do something	
	}


for文と組み合わせるとこんなかんじ。

func main() {
	sum := 0
	for sum < 10 {
		if sum == 5 {
			break // sumが5のときbreak
		}
		sum++
	}
	fmt.Println(sum) // 5
}

if, else, else if といった複数条件の書き方。

func main() {
	x := "Go"
	if x == "Go" {
		fmt.Println("OK")
	} else if x == "Python" {
		fmt.Println("NG")
	} else {
		fmt.Println("Again")
	}
}

switch

つづいて、switch文。
if-elseを短く書く方法らしい。

// 基本構文
switch expression {
	case condition:
		// do something
	}
func main() {
	os := "mac"
	switch os {
	case "mac":
		fmt.Println("mac")
	case "linux":
		fmt.Println("lunux")
	default:
		fmt.Println("windows")
	}
}
// mac

// 変数osをswitch文以外で使用しない場合、このような書き方もできる. (if文でも可)
func main() {
	switch os := "max"; os {
	case "mac":
		fmt.Println("mac")
	case "linux":
		fmt.Println("lunux")
	default:
		fmt.Println("windows")
	}
}
// windows

caseに各条件に応じた処理を書いていき、defaultでは条件に該当しない場合の処理を書く。
defaultがない場合、各条件に該当しなければ何も出力されずswitch文から出る。
また、caseは上から順番に条件に該当するまで下へいき、該当した条件があった時点で処理が終わり、switch文から出る。(breakする)

条件を書かなければ、while True文のような感じで表現できる。

func main() {
	currentHour := time.Now().Hour()
	switch {
	case current_hour < 12:
		fmt.Println("Morning")
	case current_hour < 18:
		fmt.Println("Noon")
	case current_hour > 18:
		fmt.Println("Evening")
	}

defer

遅延実行という意味らしい。
defer後にかかれた処理は、呼び出し元の関数内で処理が実行された後におこなわれる。

func main() {
	defer fmt.Println("Finally...")

	fmt.Println("First, do something")
}
// "First, do something" の出力後、"Finally..."が出力される.
// この場合、呼び出し元のmain()内処理が最後まで行われてから、deferが処理される.


// example-2
func sample() {
	defer fmt.Println("sample1")

	fmt.Println("sample2")
}
func main() {
	sample()
	defer fmt.Println("main1")
        fmt.Println("main2")
}
/*
実行順番は、
sample2
sample1
main2
main1
*/

stacking defer

deferを重ねて使う場合、はじめのものが最後に実行されるというもの。
LIFO (Last in First out) (後入れ先出し)という格納方式に基づく。

func main() {
	for i := 0; i <= 5; i++ {
		defer fmt.Println(i)
	}
	fmt.Println("start!") // 最初に実行される
}
/*
start!
5
4
3
2
1
0
*/
/* */