【Go】基本文法メモ②(フロー制御文)

# 概要

[A Tour of Go](https://tour.golang.org/)の順番に沿ってGoの基本で個人的に学習したことをまとめています。


| No | 記事 |
|------|---------|
|    1  |   [【Go】基本文法①(基礎)](https://qiita.com/k-penguin-sato/items/1d0e1c6b4bf937996cd3)|
|    2  |  __〜〜【Go】基本文法②(フロー制御文)「今ココ」〜〜__|
|    3  |  [【Go】基本文法③(ポインタ・構造体)](https://qiita.com/k-penguin-sato/items/62dfe0f93f56e4bf9157)|
|    4  |  [【Go】基本文法④(配列・スライス)](https://qiita.com/k-penguin-sato/items/daad9986d6c42bdcde90)|
|    5  |   [【Go】基本文法⑤(Maps・ Range)](https://qiita.com/k-penguin-sato/items/a320072fa09502bde3e9)|
|    6  |    [【Go】基本文法⑥(インターフェース)](https://qiita.com/k-penguin-sato/items/885a61d819cc431304f5)     |
|    7  |     [【Go】基本文法⑦(並行処理)](https://qiita.com/k-penguin-sato/items/5b09fa89d8d231bcdac8)    |
|    8  |    [【Go】基本文法総まとめ](https://qiita.com/k-penguin-sato/items/deaeab18aa416496e273)     |


# For（ループ）
Goは `for` によってループ構造を実現します。
`for` ループは `;` によって以下の３つの部分に分かれています。

```
①初期化ステートメント：最初のイテレーション(繰り返し)の前に初期化が実行されます。
②条件式：各繰り返し毎に評価されます。
③後処理ステートメント: 各繰り返しの最後に実行されます
```
①初期化ステートメントは、短い変数宣言によく利用され、その変数は `for` のスコープ内でのみ有効です。
JS等の言語の様に `()` は必要ありませんが `{}` は必要です。

```Golang
package main

import "fmt"

func main() {
 sum := 0
 for i := 0; i < 10; i++ {
    sum += i
    fmt.Println(sum)  //=> 0 1 3 6 10
 }
}
```

`①初期化ステートメント` と `③後処理ステートメント` はあくまでも任意で省略可能です。
また `;` も省略可能です。

```Golang
package main

import "fmt"

func main() {
	sum := 1
	for sum < 1000 {
		sum += sum
	}
	fmt.Println(sum) //=> 1024
}
```

# If（条件分岐）
Goの `if `は `for` と同様に `()` は必要ありませんが `{}` は必要となります。
`if` ステートメントは、 `for` のように、条件の前に、評価するための簡単なステートメントを書くことができます。（ここで宣言された変数は、 `if` のスコープ内だけで有効です。）

```Golang
package main 

import "fmt"

func condition(arg string)string{
  if v := "GO"; arg == v {
    return "This is Golang"
  }else{
    return "This is not Golang"
  }
}
func main(){
	fmt.Println(condition("Swift")) //=> This is not Golang
}
```
# Switch（条件分岐）
 Go では選択された case だけを実行してそれに続く全ての case は実行されません。

```Golang
package main 

import "fmt"

func main(){
  lang := "Go"

  switch lang {
  case "Ruby":
       fmt.Println("This is Ruby")
  case "Go":
       fmt.Println("This is Go")
  default:
       fmt.Println("This is a programming language")
  }
// => This is Go
}
```
`switch`の前に何も条件を書かない場合は`switch true`と書くのと同じです。
`if~then~else`の構文をよりシンプルに書くことが可能です。

```Golang
package main 

import "fmt"

func main(){
  lang := "Go"

  switch {
  case lang == "Ruby":
       fmt.Println("This is Ruby")
  case lang == "Go":
       fmt.Println("This is Go")
  default:
       fmt.Println("This is a programming language")
  }
// => This is Go
}
```
# Defer（遅延実行）
`defer`へ渡した関数の実行を呼び出し元の関数の終わり(`return`する)まで遅延させます。
以下の例では`defer`に渡した関数（`fmt.Println("World")`）が呼び出し元の関数（`func main()`）の終わりまで遅延されています。

```Golang
package main 

import "fmt"

func main(){
	defer fmt.Println("World")	
	fmt.Println("Hello")
	//=> Hello
    //=> World
}
```

### 複数の関数を`defer`に渡した場合
`defer`へ渡した関数が複数ある場合、その呼び出しはスタックされます。
呼び出し元の関数が`return`するとき、`defer`へ渡した関数は`新しいデータ→古いデータLIFO(last-in-first-out)`の順番で実行されます。
つまり、最初にdeferされた行が一番最後に実行される構造になります。

```Golang
package main 

import "fmt"

func main(){
	defer fmt.Println("Golang") //defer1
	defer fmt.Println("Ruby") //defer2
	fmt.Println("JS") 
	//=> JS
	//=> Ruby
	//=> Golang
}
```
上記の例では元の関数`func main()`中の` fmt.Print("JS")`を実行した後により新しい情報である`fmt.Print("Ruby")`を実行し、最後にもっとも古い情報である`fmt.Print("Golang")`を実行しています。

# 参考
[My Journey of Go②](https://k-blog0130.herokuapp.com/posts/14)
[A Tour of Go](https://tour.golang.org/flowcontrol/1)