超訳Effective Goその１

重要だから[Effective Go](https://golang.org/doc/effective_go.html)読めよ。
でもダラダラ書いてあるから超訳してみた。

とりあえずControl structures(制御構造)まで。

# イントロダクション
Goで実装するなら他の言語のことは一旦忘れろ。既存コードはそのまま移植しようとしても上手くいかない。
**Goに入ってはGoに従え**

## サンプル
Goのパッケージのソースは良サンプルだからそのまま手本にしろ。

# フォーマッティング
**gofmtしろ**。

# コメント
C++スタイルだ。`/* comment */` `// comment`
トップレベルの宣言の直前行に書いたコメントはそのままgodocでドキュメントになるぞ。
最初の行は宣言名で始まる**１行サマリー**を書くんだ。
英語のプレーンテキストで書くのがベストだ。余計な書式タグとかはいらないぞ。

# 名前
Go命名規則は重要な意味がある（例えば頭大文字でパッケージ外に公開）から手間を惜しむなよ。
ちなみに名前は短いほうがいい。**超絶長い名前付けるくらいならドキュメントを書くんだ。**

## パッケージ名

パッケージ名はそのソースファイルの**ディレクトリ名**だ。
名前は**小文字の1単語**にしろ。
万が一インポートするパッケージ名が衝突しても使うときに選択可能だし、実際混乱することなんて稀だ。

`src/encoding/base64`ににあるソースのパッケージ名は`base64`で

```go
import (
  "encoding/base64"
  "fmt"
)

func main() {
	str := base64.StdEncoding.EncodeToString([]byte("data"))
	fmt.Println(str)
}
```

ってな感じで使うぞ。

## ゲッター
Goに**ゲッター、セッター的な規約はない**が実装しても構わない。
ゲッターはエクスポートされていない`owner`フィールドに対して大文字で始まる`Owner()`って書いて**エクスポートされたフィールドっぽくアクセス**できるようにするんだ。
セッターのほうは`SetOwner()`でいいぞ。

```go
owner := obj.Owner()
if owner != user {
    obj.SetOwner(user)
}
```

## インターフェース名
**one-method interfaces（メソッドが１個しないインターフェース）**は、メソッド名に**接尾辞「er」**つけてインターフェース名にするんだ。
`Reader`、`Writer`、`Formatter`、`CloseNotifier`こういうやつ。

`Read`、 `Write`、 `Close`、 `Flush`、 `String`みたいなメソッドは上記のような既知のone-method interfaceがあるから、そのインターフェースを使えるように命名することも大事だ。例えば文字列として出力するメソッド名は`toString()`じゃなくて`String()`にして`Stringer`として扱えるようにするんだ。
既知のインターフェースと別の用途で使うなら被らない別の名前にしてくれ。

## 大文字混合
Goではスネークケース`snake_casing`的なやつじゃなくて、いわゆる**キャメルケース**`camelCasing`とか**パスカルケース**`PascalCasing`ってやつを使うんだ。

# セミコロン
**いらん。**

正確には改行直前のトークン後に**コンパイラが自動的にセミコロンを入れている**んだ。
だから、`{`の前とかに改行入れると不要なセミコロン扱いでコンパイルエラーになるぞ。

```
if i < f()  // wrong! ;
{           // wrong!
    g()
}
```
# 制御構造
Cに似てるがいろいろ違うぞ。

- **`do`や`while`はない**
- **`if`と`switch`はいろいろ初期化できる** 
- **`break`と`continue`はラベルを使って抜ける場所を決められる** 
- **`select`**っていうのが増えた

## if

**カッコつけんじゃない**。

```
if x > 0 {
    return y
}
```

もちろん`return`や`break`で制御ブロックから抜けられる。

`for`みたいにローカル変数として**初期化できる**。

```
if err := file.Chmod(0664); err != nil {
    log.Print(err)
    return err
}
```

`break`、`continue`、`goto`、`return`で終了するんだったら**`else`は省略**して次の処理を書いていい。



```
f, err := os.Open(name) // err宣言
if err != nil {
    return err
}
d, err := f.Stat()  // d宣言、err再割当て（代入）
if err != nil {
    f.Close()
    return err
}
codeUsing(f, d)
```

## 再宣言と再割り当て

余談だが、前項の例で`err`が2回宣言されているように見えるが問題ない。2回目はスコープそのままに普通の代入だ。
`:=`で複数宣言するときは、新しく宣言する変数が最低１つあればいい。

## for

Goの`for` ループはCと似て非なるものだ。**Cの`while`とかも`for`に統合**されていて、**３つの形式**があるぞ。

```go:
// ふつうのCっぽいfor
for 初期化; 条件; ループ後 { }

// whileっぽいやつ 
for 条件 { }

// for(;;)っぽいやつ　無条件ループ
for { }
```

インデックス変数はループ初期化で簡単に宣言できるぞ。

```go
sum := 0
for i := 0; i < 10; i++ {
    sum += i
}
```

`array`、`slice`、`string`、`map`、または`chan`から読取る場合は`range`を使ってループするぞ。

```go
for key, value := range oldMap {
    newMap[key] = value
}
```

`range`でキーだけが必要なら代入する変数１個だけにしたらいいぞ。

```go
for key := range m {
    if key.expired() {
        delete(m, key)
    }
}
```

値の方だけ必要なら、１番目の変数を`_`(blank identifier)にしてキーを無視すればいい。
`_`(blank identifier)はよく使うので後で説明する。

```go
sum := 0
for _, value := range array {
    sum += value
}
```

文字列の場合は`range`使うといろいろ（UTF-8を解析して個々のUnicodeコードポイントに分割、誤ったエンコードは`U+FFFD`に置換）やって`rune`を生成してくれるぞ。
(`rune`の詳細は言語仕様をみてくれ）


```go
for pos, char := range "日本\x80語" { // \x80 is an illegal UTF-8 encoding
    fmt.Printf("character %#U starts at byte position %d\n", char, pos)
}
prints

character U+65E5 '日' starts at byte position 0
character U+672C '本' starts at byte position 3
character U+FFFD '�' starts at byte position 6
character U+8A9E '語' starts at byte position 7
```

forで複数の式は使えないから、複数の変数を実行する場合は**１つの式で複数割当る**んだ。

```go
// Reverse a
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
    a[i], a[j] = a[j], a[i]
}
```

## switch

`switch`の式はCのと違って**定数か整数じゃなくてもいい**ぞ。
`case`は上から順に`switch`の式（**省略したら`true`**）と一致するまで評価される。
これはif-else-if-elseチェーンを`switch`で書けるってことだ。

```go
func unhex(c byte) byte {
    switch {
    case '0' <= c && c <= '9':
        return c - '0'
    case 'a' <= c && c <= 'f':
        return c - 'a' + 10
    case 'A' <= c && c <= 'F':
        return c - 'A' + 10
    }
    return 0
}
```

複数caseをフォールスルーはしないんだけど、**１つの`case`に複数の条件を書ける**ぞ。

```go
func shouldEscape(c byte) bool {
    switch c {
    case ' ', '?', '&', '=', '#', '+', '%':
        return true
    }
    return false
}

```

`break`ステートメントを使って`switch`を抜けることができるけど、スイッチじゃなくて外の`for`ループから抜け出したいときは、`for`ループにラベル付けをしておいて、その**ラベルを`break`**してやればいい。
もちろん`continue`ステートメントもラベルが使えるぞ。

```go
Loop:
	for n := 0; n < len(src); n += size {
		switch {
		case src[n] < sizeOne:
			if validateOnly {
				break // switchを抜ける
			}
			size = 1
			update(src[n])

		case src[n] < sizeTwo:
			if n+1 >= len(src) {
				err = errShortInput
				break Loop // forを抜ける
			}
			if validateOnly {
				break // switchを抜ける
			}
			size = 2
			update(src[n] + src[n+1]<<shift)
		}
	}

```

最後に2つのswitchステートメントを使用する`byte`sliceの比較ルーチンを書いておく。

```go
// Compare returns an integer comparing the two byte slices,
// lexicographically.
// The result will be 0 if a == b, -1 if a < b, and +1 if a > b
func Compare(a, b []byte) int {
    for i := 0; i < len(a) && i < len(b); i++ {
        switch {
        case a[i] > b[i]:
            return 1
        case a[i] < b[i]:
            return -1
        }
    }
    switch {
    case len(a) > len(b):
        return 1
    case len(a) < len(b):
        return -1
    }
    return 0
}
```

## type switch

`switch`をつかうことで`interface{}`の動的型を検出できるぞ。
`switch`の式で、**type asertion構文**を使って変数を宣言すると、**caseでその型が評価できる**んだ。
このとき宣言する変数名は、元の`interface{}`型の変数と同じ名前にするといい。その名前の変数が評価された型で使えるぞ。

```go
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
    fmt.Printf("unexpected type %T\n", t)     // %T prints whatever type t has
case bool:
    fmt.Printf("boolean %t\n", t)             // t has type bool
case int:
    fmt.Printf("integer %d\n", t)             // t has type int
case *bool:
    fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
    fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
```