Go言語  文法まとめ

# はじめに

Go言語の文法についてまとめました。

# 参考

訳のほうはだいぶ古くなっていて内容が追加されたりしたものが反映されていないので、できれば原文を読んだ方がいいと思います。

- [A Tour of Go](https://tour.golang.org)
- [A Tour of Go 日本語](https://go-tour-jp.appspot.com)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [実践Go言語（Effective Goの日本語訳）](http://golang.jp/effective_go)
- [The Go Programming Language Specification](https://golang.org/ref/spec)
- [Goプログラミング言語仕様（The Go Programming Language Specificationの日本語訳）](http://golang.jp/go_spec)

# プログラムの実行

プログラムの実行は

1. `main`パッケージの初期化
2. パッケージ中の`main`関数の呼び出し

の順で行われ、`main`関数から`return`した時点で終了する。

`main`関数は引数、返り値を持たない。

```go
func main() {
}
```

## パッケージの初期化

パッケージの初期化は

1. インポートするパッケージの初期化
2. パッケージ変数への初期値の代入
3. `init`関数の呼び出し

の順で行われる。`init`関数は引数、返り値を持たず、プログラム中で呼び出すことはできない。パッケージに複数の`init`関数がある場合は順不同で実行される。


```go
func init() {
}
```

## パッケージ

```go
package main
```

## パッケージのインポート

```go
import "fmt"
```

インポートしたパッケージの関数や定数には`.`を使ってアクセスできる。

```go
import (
	"fmt"
	"math/rand"
)

func main() {
	fmt.Println("My favorite number is", rand.Intn(10))
}
```

# コメント

## 1行のコメント

`//`からその行の終わりまで

```go
// コメント
```

## 複数行のコメント

`/*`から`*/`まで

```go
/*
	複数行
	コメント
*/
```

# 名前

## アンダースコア

名前をアンダースコア`_`にすると使わない値を捨てることができる。関数内で未使用の変数があると怒られるが、これを使えば回避できる。

## エクスポート

大文字で始まる名前は外部パッケージから参照できる。

```go
const ExportedConst = 1

var ExportedVar string

type ExportedType int

func ExportedFunc() {
}
```

## 予約語

```go
break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var
```

## 演算子、区切り文字

```go
+    &     +=    &=     &&    ==    !=    (    )
-    |     -=    |=     ||    <     <=    [    ]
*    ^     *=    ^=     <-    >     >=    {    }
/    <<    /=    <<=    ++    =     :=    ,    ;
%    >>    %=    >>=    --    !     ...   .    :
     &^          &^=
```

## 演算子の優先順位

同じ優先順位の演算子は左から結合される。たとえば、`x / y * z`は`(x / y) * z`となる。

1. `*` `/` `%` `<<` `>>` `&` `&^`
2. `+` `-` `|` `^`
3. `==` `!=` `<` `<=` `>` `>=`
4. `&&`
5. `||`

# 変数

値を入れずに初期化した場合、その型のゼロ値が入る。関数内で宣言したのに使っていない変数があるとコンパイル時エラーになるので注意。

```go
var i int
var U, V, W float64
var k = 0
var x, y float32 = -1, -2
var (
	i       int
	u, v, s = 2.0, 3.0, "bar"
)
var re, im = complexSqrt(-1)
var _, found = entries[name]
```

## 省略形式

関数の中か`if`、`for`、`switch`で変数を宣言するときに使うことができる。

```go
i, j := 0, 10
f := func() int { return 7 }
ch := make(chan int)
r, w := os.Pipe(fd)
_, y, _ := coord(p)
```

## ゼロ値

値を設定しないで初期化した変数には型ごとのゼロ値が入る。

- 論理値 `false`
- 整数 `0`
- 浮動小数点 `0.0`
- 文字列 `""`
- ポインタ、関数、インターフェイス、スライス、チャネル、マップ `nil`

# 定数

```go
const Unit = 1
const a, b, c = 3, 4, "foo"

func main() {
	const world = "世界"
}
```

## 連番の定数を作る`iota`

`()`を使ってまとめた`const`内で定数の値に`iota`を使うと、`0`から`1`ずつ増える連番の定数を作ることができる。`const ()`の外に出ると`0`に戻る。また、`const ()`内で定数の値を省略した場合は直前のものと同じ値になる。下の例ではこれを利用して`iota`を毎回書かずに連番を設定している。

```go
const (
	c0 = iota // 0
	c1 = iota // 1
	c2 = iota // 2
)

const (
	Sunday    = iota // 0
	Monday           // 1
	Tuesday          // 2
	Wednesday        // 3
	Thursday         // 4
	Friday           // 5
	Saturday         // 6
)
```

# 型
型によって値とそれに対するメソッドを定めることができる。

## 型の定義
既存の型から新しく別の型を作ることができる。

```go
type (
	Point struct{ x, y float64 }
	polar Point
)
```

別の型と扱われることを利用して、基本型にメソッドを定義することができる。

```go
type TimeZone int

const (
	EST TimeZone = -(5 + iota)
	CST
	MST
	PST
)

func (tz TimeZone) String() string {
	return fmt.Sprintf("GMT%+dh", tz)
}
```

## 型エイリアス
型に別名を付けることができ、完全に同じ型と扱われる。

```go
type (
	nodeList = []*Node
	Polar    = polar
)
```

## 型変換
型が演算子で始まる場合には`()`でくくる。

```go
float32(2.718281828)
(*Point)(p)
(<-chan int)(c)
```

### `string`、`[]byte`、`[]rune`間の変換
#### 整数値→`string`
対応するUTF-8文字列になる。

```go
string('a')  // "a"
string(-1)   // "\ufffd" == "\xef\xbf\xbd"
string(0xf8) // "\u00f8" == "ø" == "\xc3\xb8"
type MyString string
MyString(0x65e5) // "\u65e5" == "日" == "\xe6\x97\xa5"
```

#### `[]byte`→`string`

```go
string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø"
string([]byte{})                                   // ""
string([]byte(nil))                                // ""

type MyBytes []byte
string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø"
```

#### `[]rune`→`string`

```go
string([]rune{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
string([]rune{})                       // ""
string([]rune(nil))                    // ""

type MyRunes []rune
string(MyRunes{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
```

#### `string`→`[]byte`

```go
[]byte("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
[]byte("")      // []byte{}

MyBytes("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
```

#### `string`→`[]rune`

```go
[]rune(MyString("白鵬翔")) // []rune{0x767d, 0x9d6c, 0x7fd4}
[]rune("")              // []rune{}

MyRunes("白鵬翔") // []rune{0x767d, 0x9d6c, 0x7fd4}
```

# 基本型
以下の型は宣言済み。

```go
bool byte complex64 complex128 error float32 float64
int int8 int16 int32 int64 rune string
uint uint8 uint16 uint32 uint64 uintptr
```


## 論理値
論理値を表す型は`bool`で、値は`true`または`false`。

```go
true
false
```

## 文字列
文字列を表す型は`string`。実体は`byte`のスライスだが、値は不変（immutable）。つまり、一度作成すると中身を変更することはできない。

バイト単位での文字列`s`の長さは`len(s)`で取得でき、各バイトを`s[i]`のように取得できるが、`&s[i]`のようにアドレスを取得することはできない。

文字列を表すには2通りの方法がある。
1つはダブルクォート`"`で囲む方法で、改行を含めることはできず、バックスラッシュ`\`によるエスケープは解釈される。

```go
"\n"
""
"Hello, world!\n"
"日本語"
"\u65e5本\U00008a9e"
"\xff\u00FF"
```

もう1つがバッククォート`` ` ``で囲む方法で、バッククォート以外の改行を含めたすべての文字を書くことができる。バックスラッシュのエスケープは解釈されない。

```go
`abc`  // 結果は"abc"と同じ
`\n
\n`    // 結果は"\\n\n\\n"と同じ
`日本語`
```

## 数値

```go
uint8       符号なし  8-ビット 整数 (0 to 255)
uint16      符号なし 16-ビット 整数 (0 to 65535)
uint32      符号なし 32-ビット 整数 (0 to 4294967295)
uint64      符号なし 64-ビット 整数 (0 to 18446744073709551615)

int8        符号あり  8-ビット 整数 (-128 to 127)
int16       符号あり 16-ビット 整数 (-32768 to 32767)
int32       符号あり 32-ビット 整数 (-2147483648 to 2147483647)
int64       符号あり 64-ビット 整数 (-9223372036854775808 to 9223372036854775807)

float32     IEEE-754 32-ビット 浮動小数値
float64     IEEE-754 64-ビット 浮動小数値

complex64   float32の実数部と虚数部を持つ複素数
complex128  float64の実数部と虚数部を持つ複素数

byte        uint8の別名(エイリアス)
rune        int32の別名(エイリアス)
```

### インクリメント、デクリメント

```go
x++ // x += 1 と同じ
x-- // x -= 1 と同じ
```

### 整数

```go
42
```

#### 8進数

`0`を頭につけると8進数になる。

```go
0644
```

#### 16進数

`0x`を頭につけると16進数になる。

```go
0xc0ffee
```

### 浮動小数点数

整数部・小数点・小数部・指数部を持つ。`123.45e-2`だと`123`が整数部、`45`が小数部、`e-2`が指数部。

## ルーン
ルーン`rune`はUnicodeコードポイントを表す整数で、`int32`の別名。ルーン1つはシングルクォート`'`で囲んで表すことができる。

```go
'a'
'ä'
'本'
'\t'
'\000'
'\007'
'\377'
'\x07'
'\xff'
'\u12e4'
'\U00101234'
```

# ポインタ

ポインタは変数のメモリ上のアドレスを表す。`int`型の変数へのポインタの型は`*int`となる。

`&`を使ってポインタを取得できる。

```go
i := 42
p = &i
```

`*`でポインタが指す変数の値にアクセスできる。

```go
fmt.Println(*p) // ポインタpを通してiから値を読みだす
*p = 21         // ポインタpを通してiへ値を代入する
```

# 構造体

構造体は名前と型を持つ要素であるフィールドの集まり。構造体のフィールドの値には`.`を使ってアクセスする。

```go
type Vertex struct {
	X int
	Y int
}

func main() {
	v := Vertex{1, 2}
	v.X = 4
	fmt.Println(v.X)
}
```

構造体のポインタからフィールドにアクセスする際に`*`は不要。

```go
func main() {
	v := Vertex{1, 2}
	p := &v
	p.X = 1e9
	fmt.Println(v)
}
```

構造体を初期化する際に省略したフィールドの値はゼロ値になる。フィールドのキーを書かないこともできるが、その場合すべてのフィールドの値を宣言されている順に書く必要がある。

```go
var (
	v1 = Vertex{1, 2}  // キーを書かない場合
	v2 = Vertex{X: 1}  // Yはintのゼロ値の0
	v3 = Vertex{}      // XもYもintのゼロ値の0
	p  = &Vertex{1, 2} // &でポインタを取得できる
)
```

## 埋め込み

型名のみを宣言すると匿名フィールド（埋め込みフィールド）になる。これを型の構造体への埋め込みという。埋め込まれた型名をフィールド名として扱える。埋め込まれた型が持っているメソッドも構造体のメソッドとして使うことができる。

```go
type t struct {
	T1        // フィールド名はT1
	*T2       // フィールド名はT2
	P.T3      // フィールド名はT3
	*P.T4     // フィールド名はT4
	x, y  int // フィールド名はx、y
}
```

以下の例は`bufio.ReadWriter`のもので、これは`bufio.Reader`と`bufio.Writer`のポインタを埋め込んでいる。`bufio.Reader`は`io.Reader`、`bufio.Writer`は`io.Writer`をそれぞれ実装している。この埋め込みにより`bufio.ReadWriter`は`Read`メソッドと`Write`メソッドを持つことになるため、`io.Reader`、`io.Writer`、`io.ReadWriter`のすべてのインタフェースを実装している。

```go
type ReadWriter struct {
	*Reader // *bufio.Reader
	*Writer // *bufio.Writer
}
```

## タグ

フィールドの宣言の後に文字列でタグを指定することができる。タグは`key:"value"`の形式でスペース区切りで書く。通常、`"`を含むため`` ` ``で囲む。

```go
type s struct {
	microsec  uint64 `protobuf:"1"`
	serverIP6 uint64 `protobuf:"2"`
}
```

# 配列

同一の型を持つ要素を並べたもの。あとから配列の長さを変えることはできない。そのため、代わりにスライスを使うのが一般的。

```go
var a [2]string
a[0] = "Hello"
a[1] = "World"
primes := [6]int{2, 3, 5, 7, 11, 13}
```

# スライス

配列の部分列への参照であり、可変長配列のように扱える。要素が`string`型のスライスの型を`[]string`と表す。スライスは配列へのポインタ、長さ、キャパシティの3つの情報から構成されている。長さは要素数で、キャパシティはスライスの最初の要素から数えたときの参照先の配列の要素数。長さ、キャパシティはそれぞれ`len`、`cap`関数で取得することができる。

スライスは配列・配列へのポインタ・スライスから作ることができる。`s[low:high]`で`s`のインデックスが`low`から`high - 1`までの要素を持つスライスができる。`low`を省略すると`0`、`high`を省略すると`len(s)`と見なされる。

```go
a := [5]int{1, 2, 3, 4, 5}
s := a[1:4] // s == []int{2, 3, 4}
a[2:]       // a[2:len(a)]と同じ
a[:3]       // a[0:3]と同じ
a[:]        // a[0:len(a)]と同じ
```

`make`関数を使って新しくスライスを作ることができる。

```go
a := make([]int, 5)    // len(a)=5, cap(a)=5
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)]         // len(b)=5, cap(b)=5
b = b[1:]              // len(b)=4, cap(b)=4
```

## 要素の追加

`append`関数を使う。スライスの要素は同じ型の要素しか追加できないが、`[]byte`型の変数に`...`をつけた文字列を追加することができ、文字列は`[]byte`として追加される。

```go
s0 := []int{0, 0}
s1 := append(s0, 2)              // s1 == []int{0, 0, 2}
s2 := append(s1, 3, 5, 7)        // s2 == []int{0, 0, 2, 3, 5, 7}
s3 := append(s2, s0...)          // s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
s4 := append(s3[3:6], s3[2:]...) // s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}

var t []interface{}
t = append(t, 42, 3.1415, "foo") // t == []interface{}{42, 3.1415, "foo"}

var b []byte
b = append(b, "bar"...) // b == []byte{'b', 'a', 'r'}
```

## コピー

スライスの要素を`copy`関数を使ってコピーすることができる。文字列を`[]byte`にコピーすることもできる。

```go
var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
var s = make([]int, 6)
var b = make([]byte, 5)
n1 := copy(s, a[0:])           // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
n2 := copy(s, s[2:])           // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello")
```

# マップ

## 初期化
```go
m := make(map[string]int)

noteFrequency := map[string]float32{
	"C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
	"G0": 24.50, "A0": 27.50, "B0": 30.87,
}
```

## 要素の取得
存在しないキーの場合、要素の型のゼロ値が返ってくるだけなので注意。

```go
element := m[key]
```

## 要素の追加、更新

```go
m[key] = element
```

## 要素の削除

```go
delete(m, key)
```

## 要素の存在を確認
要素の取得の際に2つめの値が`true`なら存在、`false`なら存在しない。

```go
if element, ok := m[key]; ok {
}
```

## 要素数の取得

```go
size := len(m)
```

# 関数

引数名の後ろに型名を書く。2つ以上同じ型の引数をとる場合最後以外は型を省略できる。

```go
func add(x, y int) int {
	return x + y
}
```

複数の値を返すことができる。

```go
func swap(x, y string) (string, string) {
	return y, x
}
```

戻り値に名前をつけることができる。

```go
func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return x, y
}
```

## 無名関数（クロージャ）

変数に代入することも、即実行することも可能。外側の関数で定義されている変数を参照可能（クロージャ）。

```go
f := func(x, y int) int {
	return x + y
}

func(ch chan int) {
	ch <- ACK
}(replyChan)
```

## `defer`

関数内で`defer`を付けた関数呼び出しを書くと、関数が`return`する直前に実行される。複数の`defer`がある場合後のものが先に実行される（LIFO）。

```go
// 関数からreturnする直前にunlock(l)が実行される
func f() {
	lock(l)
	defer unlock(l)
	// ...
}

// 3 2 1 0の順で出力される
func g() {
	for i := 0; i <= 3; i++ {
		defer fmt.Print(i)
	}
}

// この関数は1を返す
func h() (result int) {
	defer func() {
		result++
	}()
	return 0
}
```

# メソッド

型に結びついたメソッドを定義することができ、レシーバと呼ばれるその型の引数を持つ関数として表す。メソッドは型を定義したのと同じパッケージ内でしか定義できない。
以下の例ではレシーバを`Vertex`型の`v`とすることで、`Vertex`型に`Abs`メソッドを定義している。

```go
type Vertex struct {
	X, Y float64
}

func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
```

## ポインタレシーバ

レシーバとしてポインタを受け取るようにメソッドを定義することで、メソッド内でレシーバを変更することができる。

```go
type Vertex struct {
	X, Y float64
}

func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}
```

# インタフェース
インタフェースはメソッドをまとめることができる。型がインタフェースの持つメソッドをすべて持っていればその型はインタフェースを実装したことになる。

```go
type Reader interface {
	Read(p []byte) (n int, err os.Error)
}

type Writer interface {
	Write(p []byte) (n int, err os.Error)
}
```

## 埋め込み

インタフェースの定義には、他のインタフェースのメソッドを列挙する代わりにインタフェース名を書いてもいい。これをインタフェースの埋め込みという。以下の例は`io.ReadWriter`のもので、このインタフェースは`io.Reader`と`io.Writer`を埋め込んでいる。

```go
type ReadWriter interface {
	Reader // io.Reader
	Writer // io.Writer
}
```

## 空のインタフェース

メソッドを1つも持っていないインタフェースを空のインタフェース`interface{}`という。空のインタフェースにはメソッドがないため、すべての型が自動的に空のインタフェースを実装していることになる。そのため、すべての型の値が`interface{}`型に代入可能である。

```go
func main() {
	var i interface{}
	describe(i)

	i = 42
	describe(i)

	i = "hello"
	describe(i)
}

func describe(i interface{}) {
	fmt.Printf("(%v, %T)\n", i, i)
}
```

## 型アサーション

インタフェース型の変数を値の元の型に変換するためには型アサーションを使う。変換できない場合`panic`が発生する。型アサーションは成功したかどうかの`bool`値を2つ目に返す。これを受け取れば`panic`は発生しない。失敗した場合その型のゼロ値と`false`が返る。

```go
var i interface{} = "hello"

s := i.(string)
fmt.Println(s)

s, ok := i.(string)
fmt.Println(s, ok)

f, ok := i.(float64) // panicは発生しない
fmt.Println(f, ok)

f = i.(float64) // panicが発生
fmt.Println(f)
```

# 制御構造

## `if`

```go
if x > max {
	x = max
}
```

条件の前に式を書くことができ、ここで宣言した変数は`if`ブロック内でのみ有効。

```go
if x := f(); x < y {
	return x
} else if x > z {
	return z
} else {
	return y
}
```

## `switch`

`case`に書くのは定数でなくてもよく、`,`区切りで複数書くこともでき、左のものから評価される。各`case`は上のものから評価される。`break`がなくても次の`case`に入ることはない。

```go
switch tag {
default:
	s3()
case 0, 1, 2, 3:
	s1()
case 4, 5, 6, 7:
	s2()
}
```

`switch {}`は`switch true {}`とみなされる。

```go
switch {
case x < y:
	f1()
case x < z:
	f2()
case x == 4:
	f3()
}
```

`if`と同様条件が評価される前に実行される式を書くことができる。

```go
switch x := f(); {
case x < 0:
	return -x
default:
	return x
}
```

### `fallthrough`

`case`中の最終行に`fallthrough`を書くことで次の`case`に入るようにできる。

```go
switch x := f(); {
case x%3 == 0:
	fmt.Print("Fizz")
	fallthrough
case x%5 == 0:
	fmt.Print("Buzz")
}
```

## 型`switch`
`switch x.(type) {}`と書くと変数の型で分岐することができる。変数の宣言をすることもでき、その変数の型は`case`に1つだけ書いている場合はその型になる。返り値が`interface{}`の関数`f()`の例を示す。

```go
switch i := f(x).(type) {
case nil:
	// iの型はinterface{}
case int:
	// iの型はint
case float64:
	// iの型はfloat64
case func(int) float64:
	// iの型はfunc(int) float64
case bool, string:
	// iの型はinterface{}
default:
	// iの型はinterface{}
}
```

## `for`

この`i`のように`for`変数は`for`内でのみ有効。

```go
for i := 0; i < 10; i++ {
	f(i)
}
```

### `while`
セミコロンを省略すると`for ; a < b; {}`と書いたのと同じになり、`while`のように使える。

```go
for a < b {
	a *= 2
}
```

### 無限ループ
条件も省略すると`for true {}`とみなされ、無限ループにできる。

```go
for {
}
```

### `break`

```go
for i := 0; i < 100; i++ {
	if f(i) == -1 {
		break
	}
	fmt.Println(i)
}
```

### `continue`

次の繰り返しに進む。

```go
for i := 0; i < 100; i++ {
	if f(i) == 0 {
		continue
	}
	fmt.Println(i)
}
```

### `range`

配列、スライス、文字列、マップ、チャネルの全要素に対しループする。

| 型 | 1つめの変数 | 2つめの変数 |
|----|------------|-----------|
| 配列、スライス | インデックス | インデックスに対応する要素 |
| 文字列 | バイト単位でのインデックス | 文字（ルーン） |
| マップ | キー | 値 |
| チャネル | 送信された値 |   |


#### 配列・スライス

```go
a := [3]int{2, 4, 6}
for i, v := range a {
	fmt.Println(i, v)
}
```

```go
s := []string{"あ", "い", "う"}
for i, v := range s {
	fmt.Println(i, v)
}
```

#### 文字列
Unicodeコードポイント（`rune`）単位で取り出されるが、インデックスはバイト単位。

```go
for i, v := range "寿司🍣Beer🍺" {
	fmt.Println(i, string(v))
}
```

```
0 寿
3 司
6 🍣
10 B
11 e
12 e
13 r
14 🍺
```

#### マップ
取り出される順番は保証されない。

```go
m := map[string]int{"mon": 0, "tue": 1, "wed": 2, "thu": 3, "fri": 4, "sat": 5, "sun": 6}
for key, val := range m {
	fmt.Println(key, val)
}
```

```
fri 4
sat 5
sun 6
mon 0
tue 1
wed 2
thu 3
```

#### `channel`

`channel`が`close`されるまで送信された値についてループする。

```go
var ch chan Work = producer()
for w := range ch {
	doWork(w)
}
```

変数へ代入しないで`close`されるまで待つ

```go
for range ch {
}
```

# 並行処理
## `goroutine`

関数、メソッドの呼び出し時に`go`を付けることで新たな`goroutine`が実行される。

```go
go list.Sort() // 並行して実行、終了を待たない
```

無名関数が使われることが多い。クロージャのため外側の関数の変数を参照できる。

```go
func Announce(message string, delay int64) {
	go func() {
		time.Sleep(delay)
		fmt.Println(message)
	}()
}
```

## `channel`

`channel`によって値の受け渡しと同期実行を行うことができる。`make`関数で作成するが、オプションでバッファサイズを整数で指定できる。指定しなかった場合は`0`となり、同期的な動作をできる。

```go
ci := make(chan int)           // 整数型のバッファなしチャネル
cj := make(chan int, 0)        // 整数型のバッファなしチャネル
cs := make(chan *os.File, 100) // Fileへのポインタ型のバッファありチャネル
```

値の送信、受信には`<-`を使う。`channel`にバッファがない場合、送信側と受信側の準備ができるまで送信はできない。バッファがある場合、送信側はバッファが一杯になるまでは相手を待たずに送信でき、受信側はバッファが空になるまでは受信しつづけられる。`channel`はキューのように動作する（FIFO）。また、`channel`に対して`len`でバッファにある要素数、`cap`でバッファサイズを取得できる。

```go
ch <- v   // vをチャネルchへ送信する
v := <-ch // ch から受信した変数をvへ割り当てる
```

```go
c := make(chan int)
go func() {
	list.Sort()
	c <- 1 // 終わったことを知らせるためになんでもいいから送信する
}()
doSomethingForAWhile()
<-c // 何か送信されるまで待つ（値は捨てる）
```

### `close`

送信側は送信する値がもうないことを示すために`close`できる。ただし、これは受信側がもう送信されてこないか知る必要がある場合のみ使う。ファイルと異なり`channel`は通常`close`する必要はない。

```go
close()
```

受信側は受信時の2つ目の変数が`false`かどうかで`close`されたかが分かる。

```go
v, ok := <-ch
```

また、`range`で受信していた場合、`close`されるとループから抜ける。



```go
func fibonacci(n int, c chan int) {
	x, y := 0, 1
	for i := 0; i < n; i++ {
		c <- x
		x, y = y, x+y
	}
	close(c)
}

func main() {
	c := make(chan int, 10)
	go fibonacci(cap(c), c)
	for i := range c {
		fmt.Println(i)
	}
}
```

### `select`

複数の通信操作の中から実行可能なものを選択する。`case`のうち実行可能となったものが選ばれ実行される。複数実行可能な`case`がある場合、ランダムに選択される。実行可能なものがない場合、`default`があれば実行されるが、なければどれかが実行可能になるまでそこで停止する。

```go
var c, c1, c2, c3 chan int
var i1, i2 int

select {
case i1 = <-c1: // c1で受信できた場合
case c2 <- i2: // c2にi2を送信できた場合
case i3, ok := <-c3:
	if ok {
		// c3で受信できた場合
	} else {
		// c3がcloseされた場合
	}
default:
	// どのcaseも実行できなかった場合
}

// ランダムに1か0をcに送信し続ける
for {
	select {
	case c <- 0:
	case c <- 1:
	}
}
```

# エラー

プログラムのエラーの状態を`error`型の変数で表現する。`error`型は`Error`メソッドだけを持つインタフェースとして定義されている。

```go
type error interface {
	Error() string
}
```

関数が`error`型を返す場合、`nil`かどうかでエラーが起きたかを判別できる。

```go
i, err := strconv.Atoi("42")
if err != nil {
	fmt.Printf("couldn't convert number: %v\n", err)
	return
}
fmt.Println("Converted integer:", i)
```

# `panic`

`panic`が発生した場合、その関数の実行は停止されプログラムは終了する。この際`defer`に指定された関数は実行される。

`panic`関数を使い`panic`を自分で発生させることができる。

```go
var user = os.Getenv("USER")

func init() {
	if user == "" {
		panic("no value for $USER")
	}
}
```

## `recover`

`defer`で指定した関数内で`recover`関数を呼びだすとプログラムの終了を防ぐことができる。`recover`関数は`panic`に渡された引数を返す。

```go
func server(workChan <-chan *Work) {
	for work := range workChan {
		go safelyDo(work)
	}
}

func safelyDo(work *Work) {
	defer func() {
		if err := recover(); err != nil {
			log.Println("work failed:", err)
		}
	}()
	do(work)
}
```