【Golang】 基礎

## 変数の省略定義
```golang:
// 型は自動で推測される
name := "John"

// 以下と同じ
var name string
name = "John"
```

## 名前付き戻り値
戻り値を変数として定義しておくことで、return のみで返却できる
```go:
func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return
}

func main() {
	a, b := swap(10, 7)
	fmt.Println(a, b)
}
```

## Defer
defer へ渡した関数の実行を、呼び出し元の関数の終わり(returnする)まで<font color='darkorange'>遅延させる。</font>
defer へ渡した関数が複数ある場合、その呼び出しはスタック( stack )されます。 呼び出し元の関数がreturnするとき、 defer へ渡した関数は LIFO(last-in-first-out) の順番で実行されます。

```go:
func main() {
	defer fmt.Println("world")
	fmt.Println("hello")
}
// 結果
// hello
// world

func main() {
	fmt.Println("counting")
	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}
	fmt.Println("done")
}
// 結果
// counting
// done
// 9```
// 8
// .
// .
// 0
```

## スライス
スライスは<font color='darkorange'>配列への参照</font>のようなものです。
スライスはどんなデータも<font color='darkorange'>格納しておらず</font>、単に元の配列の部分列を指し示しています。
スライスの要素を変更すると、その元となる配列の対応する要素が変更されます。
同じ元となる配列を共有している他のスライスは、それらの変更が反映されます。
```go:
func main() {
	names := [4]string{
		"John",
		"Paul",
		"George",
		"Ringo",
	}
	fmt.Println(names)

	a := names[0:2]
	b := names[1:3]
	fmt.Println(a, b)

	b[0] = "XXX"
	fmt.Println(a, b)
	fmt.Println(names)
}

// 結果
// [John Paul George Ringo]
// [John Paul] [Paul George]
// [John XXX] [XXX George]
// [John XXX George Ringo]
```

<font color='darkorange'>**注意点**</font>
配列 (スライス) を部分的に参照する際、終了インデックスに指定する値は　[実際のインデックス+1] 
<img width="450" alt="イメージ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3412108/42bfe48f-2c1d-c5d1-c0d1-514d04775103.png">

```golang:
s = []int{10, 20, 30, 40, 50, 60}
// start_index >= 2 ～ end_index < 4 までの要素
s1 := s[1:4]  //=> [20, ]
```

#### Make関数
```golang:
// Make関数
// 第1引数:スライスの型
// 第2引数:スライスの長さ
// 第3引数:スライスの容量

// 長さ5 要素int型のスライス作成
a := make([]int, 5)
==> [0, 0, 0, 0, 0] //結果 要素は全てゼロ値（int型の場合は0）で初期化される

// 長さ0 容量5 要素int型のスライス作成
// 将来的に最大で5つの要素を格納できる
b := make([]int, 0, 5)
==> [] //長さ0なので要素なし
```

## ループ
スライスをrangeで繰り返す場合、rangeは反復毎に2つの変数を返します。 1つ目の変数はインデックス( index )で、2つ目はインデックスの場所の要素のコピーです。

```golang:
func main() {
	for i, v := range pow {
		fmt.Printf("2**%d = %d\n", i, v)
	}
}
```


## Map
```golang:
// key:int value:文字列 とするマップを作成
e := make(map[int]string)
e[1] = "1st"  // 追加
e[2] = "2nd"
e[3] = "3rd"
fmt.Println(e)
delete(e, 2)  // 削除
fmt.Println(e)

// 存在確認
elem, ok := e[1]
fmt.Println("The value:", elem, "Present?", ok)

// 結果
// map[1:1st 2:2nd 3:3rd]
// map[1:1st 3:3rd]
// The value:  Present? false
```


## クロージャ

クロージャは、外部のスコープにある変数を参照し、その変数を保持して利用する関数です。Golangでは、`無名関数`（関数リテラル）を使ってクロージャを作成します。無名関数は <font color='darkorange'> **func()** ... </font> という形式で表現され、その関数型の戻り値として返すことでクロージャとして機能します。
```golang:
package main
import "fmt"

// クロージャを返す関数
func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

// count変数の値を取得する関数
func getCount() int {
    return counter()()
}

func main() {
    increment := counter()

    fmt.Println(increment()) // クロージャを呼び出して countの値を更新。1が出力される
    fmt.Println(increment()) // クロージャを呼び出して、countの値を更新。2が出力される

    fmt.Println(getCount())  // countの現在の値を取得する（クロージャの再生成はしない）2が出力される
}

```
このコードでは、counter()関数がクロージャを返しています。counter()関数内部でcount変数が定義されており、この変数はクロージャに含まれています。クロージャはcount変数にアクセスして、その値を更新しています。

increment変数はcounter()関数を呼び出してその結果として返されるクロージャを保持しています。このクロージャを呼び出すたびに、count変数が更新され、新しい値が返されます。