Golangの言語仕様を全部読んでまとめる

https://golang.org/ref/spec の和訳摘要です． 完全性はないです．

Version of Jan 14, 2020

##[ソースコードの表現](https://golang.org/ref/spec#Source_code_representation)
ソースコードはUTF-8である．

###[文字](https://golang.org/ref/spec#Characters)
```
改行 = LF
unicode文字 = Unicodeの"Letter"
unicode数字 = Unicodeの"Number, decimal digit"
```

###[文字と数字](https://golang.org/ref/spec#Letters_and_digits)
```
文字 = unicode文字と"_"
```

##[字句要素](https://golang.org/ref/spec#Lexical_elements)

###[コメント](https://golang.org/ref/spec#Comments)
```
プログラム // 行コメント
/* 複数行
コメント */
```

###[トークン](https://golang.org/ref/spec#Notation)

トークンは5種類

- 識別子
- キーワード
- 演算子
- 約物(句読点)
- リテラル

空白(スペース, タブ， CR, LF)は無視される

###[セミコロン](https://golang.org/ref/spec#Semicolons)
セミコロンは文の終りを示す
一行に複数文を書きたいときのみ， 明示的にセミコロンを必要とする

###[識別子](https://golang.org/ref/spec#Identifiers)
識別子は文字始まり， 文字+unicode数字が続く

###[キーワード](https://golang.org/ref/spec#Keywords)
```
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
```

###[演算子と約物](https://golang.org/ref/spec#Operators_and_punctuation)
```
+    &     +=    &=     &&    ==    !=    (    )
-    |     -=    |=     ||    <     <=    [    ]
*    ^     *=    ^=     <-    >     >=    {    }
/    <<    /=    <<=    ++    =     :=    ,    ;
%    >>    %=    >>=    --    !     ...   .    :
     &^          &^=
```

###[整数リテラル](https://golang.org/ref/spec#Integer_literals)
`_`を区切り文字として使える． `123_456`

`0b`で2進， `0o`で8進， `0x`で16進を示す

###[小数リテラル](https://golang.org/ref/spec#Floating-point_literals)
`．`が1つ含まれる数字

- `1e+01`： 指数表記
- `0x_1`: 16進
- `0x_1P-16`: 16進+指数表記

###[虚数リテラル](https://golang.org/ref/spec#Imaginary_literals)
整数， 小数の最後に`i`をつけると虚数

###[Runeリテラル](https://golang.org/ref/spec#Rune_literals)
`'Rune'`はUnicodeのコードポイント．

- `'ä'`はUTF-8では0xc3 0xa4だが， RuneではU+00E4
-`'\377'` `'\x07'` `'\xff'` `'\u12e4'`

###[文字列リテラル](https://golang.org/ref/spec#String_literals)

- `"バックスラッシュエスケープされる文字列\n"`
- `` `エスケープされない文字列` ``

##[定数](https://golang.org/ref/spec#Constants)
- リテラルは定数
- `unsafe.Sizeof(式)`は定数
- `cap(式)` `len(式)` は定数のことがある
- `real(複素定数)` `imag(複素定数)` は数値定数
- `true` `false` 真偽値定数
- `iota` 整数定数

型名を省略したときのデフォルトは `bool`, `rune`, `int`, `float64`, `complex128`, `string`


##[変数](https://golang.org/ref/spec#Variables)
変数は静的型付けされる

`interface{}`型は任意の値を代入できる

##[型](https://golang.org/ref/spec#Types)
型は配列，構造体，ポインタ，関数，インターフェース，スライス，マップ，チャンネル

###[メソッド集合](https://golang.org/ref/spec#Method_sets)
型はメソッドを持つ

- インターフェースは，そのインターフェスをメソッドとして持つ
- 型`T`は，`T`をレシーバにするメソッドを持つ
- 型`*T`は，`*T`か`T`をレシーバにするメソッドを持つ
- 構造体が埋め込みフィールドを含む場合，そのメソッドも持つ

###[真偽値型](https://golang.org/ref/spec#Boolean_types)
型`bool`は
`true`か`false`

ゼロ値は`false`
`==`による比較可能

###[数値型](https://golang.org/ref/spec#Numeric_types)
```
uint8       非負8-bit (0 to 255)
uint16      非負16-bit (0 to 65535)
uint32      非負32-bit (0 to 4294967295)
uint64      非負64-bit (0 to 18446744073709551615)

int8        8-bit  (-128 to 127)
int16       16-bit (-32768 to 32767)
int32       32-bit (-2147483648 to 2147483647)
int64       64-bit (-9223372036854775808 to 9223372036854775807)

float32     IEEE-754 32-bit 浮動小数点
float64     IEEE-754 64-bit 浮動小数点

complex64   float32 複素数
complex128  float64 複素数

byte        uint8のエイリアス
rune        int32のエイリアス

uint        32-bit or 64-bit
int         uintと同じ大きさ
uintptr     ポインタを格納できる大きさ
```

ゼロ値は`0`
`==`による比較 `<`などによる順序比較可能

###[文字列型](https://golang.org/ref/spec#String_types)
文字列の長さ`len(文字列)`はバイト列の長さ
文字列は変更できない

`文字列[添字]`でバイト列を参照する
`&文字列[添字]`は不可
`文字列[添字] = 文字`は不可

`文字列[low : high]`は部分文字列を返す

ゼロ値は`""`
nilにならない

`==`による比較が可能 `<`などによる順序比較可能
byte列による辞書順で比較される


###[配列型](https://golang.org/ref/spec#Array_types)

配列`[要素数]型T`は，型Tを要素数個格納できる型
要素数は静的に決定
`[1][2][3]int`は`[1]([2]([3]int))`
`make([要素数]型)` ゼロ初期化された配列

`len(配列), cap(配列)`は要素数
`[要素数]型{要素0, 要素1, …}` 配列の合成リテラル
`[...]型{要素0, 要素1, …}` 要素数は`...`とすると要素数となる
指定された要素数に対して要素が足りなければ要素はゼロ値となる


`配列[添字]`により要素が得られる
`配列[low : high]`によりスライスが得られる
得られたスライスは元の配列と要素を共有している
スライスを書き換えると配列も書き換わる

ゼロ値はそれぞれの要素がゼロ値となる
`==`による比較が可能 個別の要素を比較する

###[スライス型](https://golang.org/ref/spec#Slice_types)
スライス`[]型T`は，型Tを格納する列の型
要素数が動的に決定

`len(スライス)`は要素数
`cap(スライス)`で予備を含めたスライスの大きさ=キャパシティーを得られる
`make(スライス型, 長さ, キャパシティー)` キャパシティーを与えてゼロ初期化されたスライス
`new([キャパシティー]スライス型)[0:長さ]`は上と等価

`[]型{要素0, 要素1, …}` スライスの合成リテラル． キャパシティーは指定できない．
`スライス[low : high]`によりスライスが得られる
得られたスライスはもとのスライスと要素を共有している
スライスを書き換えるともとのスライスも書き換わる

ゼロ値はnil
スライス型のnilは要素数0のスライスのように振る舞う
`==`による比較ができない

###[構造体](https://golang.org/ref/spec#Struct_types)
struct {複数のフィールド}`は構造体型
変数0, 変数1, … 型`は名前付きフィールド (`x int`, `x, y int`)
`型` だけ書くと埋め込みフィールドとなり， フィールド名は型と同じ
`_ 型`はパディング

`型{キー: 値…}` 合成リテラル
キーを省略した場合，structの順番となる
値が足りないときはゼロ値となる

構造体Sに型Tを埋め込むと，型Tのフィールドとメソッドは構造体Sでも参照できる

```go
type T struct {
  X int
}
type S struct {
  T // Tを埋め込む
}

func main() {
  s := S{T{1}}
  // s.X は S.T.X と同じ
  fmt.Printf("%#+v:  %v === %v", s, s.X, s.T.X)
  // main.S{T:main.T{X:1}}:  1 === 1
}
```

フィールドは文字列のタグを持つ
タグが未指定の場合，空文字列のタグを持つ

リフレクションで参照できる

```golang
struct {
	microsec  uint64 `protobuf:"1"`
	serverIP6 uint64 `protobuf:"2"`
}
```

ゼロ値はそれぞれのフィールドをゼロ値で初期化する
`==`による比較可能 個別のフィールドを比較する

###[ポインタ型](https://golang.org/ref/spec#Pointer_types)

`*T`は`T`のポインタ型

`&値`によりポインタが得られる
`*ポインタ`により値を参照する

ゼロ値はnil
nilを参照すると実行時パニック
`==`による比較可能

###[関数型](https://golang.org/ref/spec#Function_types)

`func(引数) 返り値`は関数型

ゼロ値はnil
nilを呼び出すと実行時パニック
`==`による比較不可能

###[インターフェース型](https://golang.org/ref/spec#Interface_types)
`interface{複数のシグネチャ}`はインターフェース型
シグネチャは `メソッド名(引数)返り値`

インターフェースIのすべてのシグネチャが型Tのメソッドの時， 型TはインターフェースIを実装していると言う

`interface{}`は要求するメソッドが無いので， 全ての型が実装している

インターフェースは他のインターフェースを埋め込める
埋め込まれたインターフェースのシグネチャを取り込む

`ReadWriter`は`Read`と`Write`と`Close`を持つ

```golang
type Reader interface {
	Read(p []byte) (n int, err error)
	Close() error
}
type Writer interface {
	Write(p []byte) (n int, err error)
	Close() error

type ReadWriter interface {
	Reader
	Writer
}
```

ゼロ値はnil
`==`による比較可能 元の型として比較する

###[マップ型](https://golang.org/ref/spec#Map_types)
`map[キー型]値型`はマップ型
`make(map[キー型]値型, キャパシティー)`でキャパシティー付きのマップが作られる
`map[キー型]値型{キー0: 値0, キー1: 値1, …}`
`len(マップ)`は要素数

`マップ[キー]`は値とその存在を返す
  + **キーが存在するとき**，その値と`true`
  + **存在しないとき**，ゼロ値と`false`
`v, ok = m[0]`

ゼロ値はnil
nilはキーが存在しないマップとして振る舞う
`==`による比較不可能

###[チャンネル型](https://golang.org/ref/spec#Channel_types)

スレッドセーフなキュー

`chan 型T`は 型Tを送受信するチャンネル型
`chan <- 型T`は 型Tを送信するチャンネル型
`<- chan 型T`は 型Tを受信するチャンネル型

`make(chan 型T， キャパシティー)`はチャンネルを作る唯一の方法
キャパシティーはチャンネルのキューの大きさを示す

`len(チャンネル)`はキュー内の要素数
`cap(チャンネル)`はキューの大きさ


**バッファーに要素があるとき**， 受信は成功する
**バッファーに要素がないとき**， 受信は送信されるまでブロックする
**バッファーが足りているとき**, 送信は成功する
**バッファーの要素がいっぱいのとき**， 送信は受信されるまでブロックする

ゼロ値はnil
チャンネル型のnilは何も送受信されない

`close(チャンネル)`によりチャンネルをクローズできる

`==`による比較可能 同じmake()によって生み出されたか判定する

##[型と値の性質](https://golang.org/ref/spec#Properties_of_types_and_values)

###[型の同一性](https://golang.org/ref/spec#Type_identity)
- 異なるパッケージの非公開名前は区別される
- シグネチャの引数や返り値の名前は無視される
- キャパシティーは無視される
- エイリアスは同一の型となる

###[代入可能](https://golang.org/ref/spec#Assignability)
値xが型Tに代入可能である とは 次のいずれかを満たすことである:

- xの型VがTと同一である
- xの型VとTが同一の基底型を持ち， VとTの少なくともどちらかがDefined型ではない
- Tがインターフェース型であり， xがTを実装している
- x が送受信チャンネルでTがチャンネル型であり， VとTが同一の要素型をもち， VとTの少なくともどちらかがDefined型ではない
- xがnilであり，Tがポインタ，関数，スライス，マップ，チャンネル，インターフェースである
- xが定数であり，Tの値として表現可能

Defined型は， `type 型名 型`で定義された型名の型のこと

`type T1 T`， `type T2 T`のとき，
Tの値はT1, T2に代入できるが， T1の値をT2に代入することはできない

###[表現可能](https://golang.org/ref/spec#Representability)

定数xが型Tの値として表現可能であるとは，
要するに，定数がその型として扱えるということ

##[ブロック](https://golang.org/ref/spec#Blocks)

ブロックは文のリスト `{文; 文; …}`

暗黙的にブロックが生成される

- すべてのGoのソースコード全体=宇宙ブロック
- それぞれのパッケージのソースコード全体
- ファイル全体
- `if`, `for`, `switch`
- `switch`, `select`のブランチ

ブロックによってスコープが規定される

##[宣言とスコープ](https://golang.org/ref/spec#Declarations_and_scope)

宣言は， 定数， 型， 変数の3種類
トップレベル宣言は， 宣言に加えて関数宣言とメソッド宣言の5種類

boolなどの事前宣言識別子は宇宙ブロックのスコープに属する
トップレベルの宣言はパッケージのスコープに属する
インポートしたパッケージはファイルのスコープに属する

他の名前は最も内側のブロックのスコープに属する

###[ラベルのスコープ](https://golang.org/ref/spec#Label_scopes)

定義されたラベルは用いる必要がある
ラベルは関数のブロックのスコープに属する． ラベル以外の識別子とは衝突しない

###[ブランク識別子](https://golang.org/ref/spec#Blank_identifier)
`_`はブランク識別子として特別な意味を持つ

###[事前宣言識別子](https://golang.org/ref/spec#Predeclared_identifiers)

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

Constants:
	true false iota

Zero value:
	nil

Functions:
	append cap close complex copy delete imag len
	make new panic print println real recover
```

###[エクスポートされる識別子](https://golang.org/ref/spec#Exported_identifiers)
識別子の初めの文字がUnicodeの大文字クラス("Lu")であり，
パッケージブロックで宣言された名前である時

その識別子はエクスポートされる

###[識別子の唯一性](https://golang.org/ref/spec#Uniqueness_of_identifiers)

同じスコープに同じ識別子は持てない

###[定数定義](https://golang.org/ref/spec#Constant_declarations)

`const 定数名 = 定義` により定数を定義できる
`const 定数名 型 = 定義` により型を指定できる

`iota`は`const()`の中で宣言ごとに0から1ずつ増える特別な値である． 

```golang
const (
	Sunday = iota
	Monday
	Tuesday
	Wednesday
	Thursday
	Friday
	Partyday
	numberOfDays  // this constant is not exported
)
```

###[Iota](https://golang.org/ref/spec#Iota)

1つの宣言の中では`iota`は同じ値となる

```golang
const (
	bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0  (iota == 0)
	bit1, mask1                           // bit1 == 2, mask1 == 1  (iota == 1)
	_, _                                  //                        (iota == 2, unused)
	bit3, mask3                           // bit3 == 8, mask3 == 7  (iota == 3)
)
```

###[型宣言](https://golang.org/ref/spec#Type_declarations)


#### エイリアス型宣言
`type エイリアス名 = 型`

エイリアスは元の型と同一の型である

#### 型宣言
`type 型名N 型T`

基底型をTとして新しい型を型名Nとして作る．
型名NはDefined型となる． 

すなわち，`type TimeZone int`はintと異なる振る舞いをする
また，Defined型はメソッドを持つことができる．

```golang
type TimeZone int

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

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

###[変数宣言](https://golang.org/ref/spec#Variable_declarations)
`var 変数名 型 = 値`で変数宣言
型と値は省略可能

参照されない変数はエラーとなる

`_`により値を捨てることができる

```golang
var _, found = entries[name]
```

###[短縮変数宣言](https://golang.org/ref/spec#Short_variable_declarations)
`変数名 := 値`は `var 変数名 = 値`の省略としてほとんど振る舞う
ただし`var`と異なり， 一部の変数への代入が可能
少なくとも1つは新しい変数を定義する必要がある

###[関数定義](https://golang.org/ref/spec#Function_declarations)

`func 識別子 シグネチャ ブロック`により関数が定義される

返り値を返すならばブロックの最後のreturnを省略できない
ただし， if-elseと条件のないforのあるときは省略できることがある(see 終端文)

関数のブロックを省略した場合，アセンブリルーチンなどでGo以外の外部から定義が与えられることを想定される

###[メソッド宣言](https://golang.org/ref/spec#Method_declarations)
`func (レシーバ変数 レシーバ型) 識別子 シグネチャ`によりメソッドが定義される

レシーバ型(*T， T)はTがDefined型である必要がある

メソッドの型は`func (レシーバ型, メソッドの型...) メソッドの返り値`

##[式](https://golang.org/ref/spec#Expressions)
###[被演算子](https://golang.org/ref/spec#Operands)
被演算子はすべてのリテラルと識別子と修飾識別子と`(式)`である

###[修飾識別子](https://golang.org/ref/spec#Qualified_identifiers)
識別子にパッケージ名をつけることで別のパッケージの識別子を参照できる

`パッケージ名.識別子`

###[合成リテラル](https://golang.org/ref/spec#Composite_literals)

チャンネル以外の型には`{}`によるリテラルがある

合成リテラルの例はそれぞれの型の節に移動した

複数の型が合成された型のとき， 内側の型名を省略できる

次の2つは同じ:
```golang
map[string]Point{"orig": {0, 0}}
map[string]Point{"orig": Point{0, 0}}
```

###[関数リテラル](https://golang.org/ref/spec#Function_literals)

`func シグネチャ 関数本体`は関数であり，クロージャを作る
外側の変数を参照するための環境を持つ
`()`で呼び出すことができる

###[基本式](https://golang.org/ref/spec#Primary_expressions)
###[セレクタ](https://golang.org/ref/spec#Selectors)

`x.f`はxのフィールドかメソッドを返す
xが埋め込みフィールドを持つ場合， 幅優先で再帰的に探索する

- **xの型(T, *T)でTがポインタでもインターフェースでもない** 
  + 探索時に最も浅いところのfを返す
  + 同じ深さに同じfがあるならば不正
- **xの型がインターフェースI**
  + xの動的な実際の型のfを返す．
  + fがインターフェースIのメソッドでないならば不正
- **xがポインタ型** (例外)
  + xの実体である`(*x).f`が不正でないならx.fは`P(*x).f`の短縮となる
- **xがポインタ型でnil**
  + 実行時パニック
- **xがインターフェースでnil**
  + x.fを評価もしくは呼び出した時に実行時パニック

###[メソッド式](https://golang.org/ref/spec#Method_expressions)
`型.メソッド`や`(*型).メソッド`により関数が得られる

###[メソッド値](https://golang.org/ref/spec#Method_values)
`値.メソッド`により関数が得られる

###[添字式](https://golang.org/ref/spec#Index_expressions)
`値a[添字i]` 

- **値aがポインタのとき**，`(*値a)[添字i]`と等価
- **マップ，配列，スライス，文字列のとき** それぞれの型のところで示した 

###[スライス式](https://golang.org/ref/spec#Slice_expressions)

`値a[low:higth]`は部分文字列やスライスを返す
値aがポインタのとき，`(*値a)[low:high]`と等価

`low`を省略すると0，`high`を省略すると`len(値a)`となる

###[型アサーション](https://golang.org/ref/spec#Type_assertions)

`値x.(型T)`により実行時に型変換ができる

- **型Tがインターフェースのとき**，xはTを実装している必要がある
- **型Tがインターフェースでないとき**，Tはxの型を実装している必要がある

そうでなければ実行時パニックを起こす

ただし`v, ok := x.(T)`の形で呼び出した場合は， 実行時パニックを起こさない
かわりにvがゼロ値， okがfalseとなる

###[呼び出し](https://golang.org/ref/spec#Calls)

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

返した複数の値は次のどれかを行う必要がある

- 分割代入する: `x, y := f()`
- returnする: `return f()`
- 合成する: `g(f())`

###[多引数関数 ...引数](https://golang.org/ref/spec#Passing_arguments_to_..._parameters)
who ...string)

関数の最後の引数を`...型`にできる．
渡した引数がスライスとして渡される

```golang
func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")
```

`スライス...`で`...引数`に渡すことができる

```golang
s := []string{"James", "Jasmine"}
Greeting("goodbye:", s...)
```

###[演算子](https://golang.org/ref/spec#Operators)

###[数値演算](https://golang.org/ref/spec#Arithmetic_operators)
- **数値** `+` `-` `*` `/` `%`
- **ビット** `|` `^` `<<` `>>` `&` `&^`
- **単項演算子** `+` `-` `^` 

`&^`はbit clear(AND NOT)
存在理由→[stack overflow](https://stackoverflow.com/questions/43782187/why-does-go-have-a-bit-clear-and-not-operator/43783202)

オーバーフローしてもパニックではなくwrap-aroundする

`x < x+1`が常に`true`とは限らない

小数の演算は積和演算(FMA)などの丸めで結果が異なることがある

文字列は `+` で結合できる
ただし， 多くの文字列を結合するならば`strings.Builder`を用いるべき

###[比較演算](https://golang.org/ref/spec#Comparison_operators)
- **比較** `==` `!=` 
- **順序** `<` `<=` `>` `>=`

比較する2値は互いに代入可能である必要がある

スライス，マップ，関数は比較できない

- **真偽値，整数，小数** 比較可能かつ順序付け可能
- **複素数** real→imagの辞書順比較で順序付けされる
- **文字列** bit列での辞書順比較で順序付けされる
- **ポインタ** 比較可能． 大きさゼロの要素のポインタ値は異なることがある
- **チャンネル** makeで作られた同じチャンネルであるか比較する
- **インターフェース** 同じ型で同じ値か比較する
- **構造体** すべてのフィールドの値が同じか比較する
- **配列** すべての要素が同じか比較する


###[論理演算子](https://golang.org/ref/spec#Logical_operators)
- **短絡演算** `||` `&&`
- **単項演算子** `!`

###[アドレス演算](https://golang.org/ref/spec#Address_operators)
- **参照** `&x`
- **参照先の値を得る** `*x`

###[受信演算](https://golang.org/ref/spec#Receive_operator)

- **受信** `<-ch`

受信する．
バッファーが無いときは送信があるまでブロックする

`x, ok = <-ch`のとき， 受信に成功したかクローズしたかを返す
受信に成功すればok=trueとなる

###[コンバージョン](https://golang.org/ref/spec#Conversions)

`型T(値x)`
コンパイル時に検査される型変換

**xが定数の時** 値xが型Tとして表現可能でなければ不正
**xが定数でない時** 次のどれかを満たす

- xがTに代入可能
- 構造体のタグを無視して， xの型がTの基底型と同一
- 構造体のタグを無視して， xの型とTのポインター型がDefined型ではなく，それらの基底型が同一
- xが整数か小数で，Tが整数型か小数型
- xが複素数で，Tが複素数型
- xが整数か[]byteか[]runeで，Tが文字列
- xが文字列で， Tが[]byteか[]rune

すなわち，次のキャストが可能

- 構造体のタグを無視するキャスト
- 数値のキャスト
- 文字列とスライスのキャスト


###[定数式](https://golang.org/ref/spec#Constant_expressions)

定数の演算は定数式になる

###[評価順](https://golang.org/ref/spec#Order_of_evaluation)

関数の引数の評価は左から右に行われる

##[文](https://golang.org/ref/spec#Statements)

###[終端文](https://golang.org/ref/spec#Terminating_statements)
return以外でも終了文がある
- `return` `goto` `panic`
- `if-else` `for` ` switch` `select` (条件あり)

###[空文](https://golang.org/ref/spec#Empty_statements)
空文は何もしない

###[ラベル付き文](https://golang.org/ref/spec#Labeled_statements)

```
ラベル: 文
```

###[式文](https://golang.org/ref/spec#Expression_statements)
式は文である

###[送信文](https://golang.org/ref/spec#Send_statements)

チャンネルに値を送信する
```golang
ch <- 3
```

###[インクリメント・デクリメント文](https://golang.org/ref/spec#IncDec_statements)
```golang
x++
x--
```

###[代入](https://golang.org/ref/spec#Assignments)
```golang
x = 1
x += 1
a, b = b, a
```
###[If文](https://golang.org/ref/spec#If_statements)
```golang
if x := f(); x < y {
	return x
} else if x > z {
	return z
} else {
	return y
}
```

###[Switch文](https://golang.org/ref/spec#Switch_statements)


#### 式Switch文
```golang
switch tag {
default: s3()
case 0, 1, 2, 3: s1()
case 4, 5, 6, 7: s2()
}
switch { // switch trueと等価
case x < y: f1()
case x < z: f2()
case x == 4: f3()
}
```

#### 型Switch文
`switch 変数 := 変数.(type)`
順番に型アサーションを試し，成功したブランチを実行する

```golang
switch i := x.(type) {
case nil:
    print("x is nil")
case int:
    print(i+1)
}
```

###[For文](https://golang.org/ref/spec#For_statements)

### 1条件For
```golang
for a < b {
  a *= 2
}
for { // for trueと等価
  if a < b {
    break
  }
}
```

###　3条件For
```golang
for i := 0; i < 10; i++ {
  f(i)
}
```

### range For
```golang
for i, v := range a {
  print(i, v)
}
```

- **aが配列，スライスの時** iは添字， vは要素
- **aが文字列の時** iはUTF-8での添字，vはRune
- **aがマップの時** iはキー，vは要素 順序不定 ループ中の要素追加は不定
- **aがチャンネルの時** **1要素** チャンネルがCloseするまで受信ループ

###[Go文](https://golang.org/ref/spec#Go_statements)
最後の関数適用がゴルーチンとして並列に実行される

```golang
go Server()
go func(ch chan<- bool) { for { sleep(10); ch <- true }} (c)
```
###[Select文](https://golang.org/ref/spec#Select_statements)

実行できる受信/送信を1つ当確率にランダムに実行する．
すべての受信/送信がブロックした場合，defaultがあればdefaultを実行する

```golang
select {
case <- c1:
case x := <- c2:
default: // ブロックしない
}
// 0，1をランダムに送信し続ける
for { 
  select {
  case c <- 0: 
  case c <- 1:
  }
}
```
###[Return文](https://golang.org/ref/spec#Return_statements)

名前付き返り値を用いることができる

```golang
func complexF3() (re float64, im float64) {
	re = 7.0
	im = 4.0
	return
}
```
###[Break文](https://golang.org/ref/spec#Break_statements)
一番内側の`for` `switch` `select`を抜ける
もしくは指定したラベルまで抜ける

###[Continue文](https://golang.org/ref/spec#Continue_statements)
`for`に戻る
もしくは指定したラベルの`for`に戻る

###[Goto文](https://golang.org/ref/spec#Goto_statements)

指定したラベルに処理を移す

###[Fallthrough文](https://golang.org/ref/spec#Fallthrough_statements)
`switch`内で次のブランチも実行する

###[Defer文](https://golang.org/ref/spec#Defer_statements)
最後の関数呼び出しを，現在の関数から抜ける`return`や`panic`のタイミングで実行する
`defer`の実行は文の順番と逆に行われる

##[組み込み関数](https://golang.org/ref/spec#Built-in_functions)
###[Close](https://golang.org/ref/spec#Close)
チャンネルを閉じる

次の時実行時パニック
- 閉じたチャンネルを閉じる
- 閉じたチャンネルに送信する
- nilを閉じる

###[長さとキャパシティ len/cap](https://golang.org/ref/spec#Length_and_capacity)

それぞれの型の説明で説明済み

###[確保 new](https://golang.org/ref/spec#Allocation)
`new(T)`は型のゼロ値を返す
ほとんどの場合`T{}`と等価

###[スライス，マップ，チャンネルの生成](https://golang.org/ref/spec#Making_slices_maps_and_channels)
`make(型, 要素数 キャパシティ)`を指定できる

###[スライスへの追加とコピー append/copy](https://golang.org/ref/spec#Appending_and_copying_slices)

appendでスライスの末尾に複数要素を追加できる
**appendの第1引数は使い回され変更を受けることがある**

```golang
b := append(a, 1, 2)
b := append(a, c...)
```

copyはsrcの要素をdstに代入する

```golang
copy(dst, src []T) int
```

###[マップからキーを削除 delete](https://golang.org/ref/spec#Deletion_of_map_elements)
キーが存在しない場合は何もしない
```golang
delete(m, k)
```
###[複素数演算 complex/real/imag](https://golang.org/ref/spec#Complex_numbers)

```golang
complex(realPart, imaginaryPart floatT) complexT
real(complexT) floatT
imag(complexT) floatT
```

###[パニックとリカバリ panic/recover](https://golang.org/ref/spec#Handling_panics)

panicは直ちにすべての関数を抜けようとする

```golang
func panic(interface{})
func recover() interface{}
```

deferでrecover()を呼ぶとパニックの送出が止まる
パニックしたときの引数が得られる

```golang
func protect(g func()) {
	defer func() {
		log.Println("done")  // Println executes normally even if there is a panic
		if x := recover(); x != nil {
			log.Printf("run time panic: %v", x)
		}
	}()
	log.Println("start")
	g()
}
```

###[ブートストラッピング print/println](https://golang.org/ref/spec#Bootstrapping)
デバッグ出力， 標準エラー出力に出ることが多い

```golang
print("Hello")
println("World")
```

##[パッケージ](https://golang.org/ref/spec#Packages)
Goのビルド単位

###[ソースファイル](https://golang.org/ref/spec#Source_file_organization)

Goのソースファイルは

```
package パッケージ名
複数のインポート宣言
```
から始まる

###[インポート宣言](https://golang.org/ref/spec#Import_declarations)

パッケージをインポートするときは，
パッケージ名に別名をつけることや
現在のパッケージと名前空間を共有することができる

パッケージ名は実装依存

```golang
import "lib/math" → math.Sin
import m "lib/math" → m.Sin
import . "lib/math" → Sin
```

##[プログラムの初期化と実行](https://golang.org/ref/spec#Program_initialization_and_execution)

###[ゼロ値](https://golang.org/ref/spec#The_zero_value)
確保された変数は初期値がない場合，ゼロ値になる．
`false` `0` `""` `nil`のいずれか

###[パッケージの初期化](https://golang.org/ref/spec#Package_initialization)
パッケージグローバルの変数は依存の解決されたものから上から順番に初期化される．

パッケージの`init()`が呼ばれる．
`init()`は何回でも定義できる．
`init()`はプログラムの他の場所から参照できない．

インポートされたパッケージが先に初期化される．
複数回インポートされるパッケージは1回だけ初期化される．
パッケージ間の循環参照は起こせない．


###[プログラムの実行](https://golang.org/ref/spec#Program_execution)

mainパッケージの`main()`が実行される，

##[エラー error](https://golang.org/ref/spec#Errors)
`error`型はインターフェースである．

```golang
type error interface {
	Error() string
}
```
nilはエラーのないことを示す．


##[実行時パニック panic](https://golang.org/ref/spec#Run_time_panics)

`panic`関数はerror型を受け取り，実行時パニックを起こす

##[システム関係](https://golang.org/ref/spec#System_considerations)

###[unsafeパッケージ](https://golang.org/ref/spec#Package_unsafe)

```golang
package unsafe

type ArbitraryType int  // shorthand for an arbitrary Go type; it is not a real type
type Pointer *ArbitraryType

func Alignof(variable ArbitraryType) uintptr
func Offsetof(selector ArbitraryType) uintptr
func Sizeof(variable ArbitraryType) uintptr
```

Offsetofは要素のオフセットを返す

```golang
uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
```

Alignof(x)はアライメントを返す

```golang
uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0
```

###[大きさとアライメントの保証](https://golang.org/ref/spec#Size_and_alignment_guarantees)

数値型は固定サイズである．

```
type                                 size in bytes

byte, uint8, int8                     1
uint16, int16                         2
uint32, int32, float32                4
uint64, int64, float64, complex64     8
complex128                           16
```

structのアライメントは要の最大のアライメントと等しい．
arrayのアライメントは要素のアライメントと等しい

ゼロ要素のstructやarrayは0より大きい大きさを持つことがある．
ゼロ要素の異なる変数が同じメモリに配置されることがある．