Go Codereview Comments 超訳

はじめに

Go Codereview Comments(日本語訳) を読んだ時の備忘録です。
かなり省略していて、主観が入っている気がします。
内容に関しては一切責任を負いません。

Go Codereview Comments

go fmt

go fmt 使え。
世の中にあるGoのコードほとんど使用しているし、自動で機械的にスタイル修正してくれるから。
goimports もいいぞ。

Comment Sentences

// 対象の名前 英文コメント . でコメント書いてね

// Request represents a request to run a command.
type Request struct { ...

Contexts

Contextを使うときは構造体のメンバーに含めるな。
メソッドとして第一引数で渡せ。

func F(ctx context.Context, /* other arguments */) {}

Copying

別のパッケージから構造体をコピーするときは注意深く。
例えば、bytes.Buffer をコピーすると、コピー先でオリジナルのデータを参照しているから副作用が起きるかも。

Crypt Rand

鍵の生成のために math/rand を使うな。
crypto/rand の Reader を使え。

Declaring Empty Slices

スライスの宣言時は

t := []string{}

ではなく

var t []string

を使え。
インターフェイスを設計するときは、nilのスライスと長さ0のスライスを区別しないように扱いましょう。

Doc Comments

すべての最上位にあったり外部に公開されているものはdocコメントがなければならない。

Don’t Panic

エラーハンドリングで panic 使うな。error 使え。

Error Strings

エラー文字列はWrapされるから頭文字を大文字にしたり句読点をつけるな。

fmt.Errorf("something bad")

Examples

新しいパッケージを追加したとき、使い方のサンプルを含めましょう。

Goroutine Lifetimes

goroutineを生成するとき、いつ終了されるか明確にしよう。
並行処理はgoroutineの生存期間が明確になるように、十分にシンプルに書きましょう。

Handle Errors

_ でエラーを無視するな。チェックしろ。

Imports

package をリネームするのはやめましょう。
import を空行で幾つかのグループに分けましょう。
標準パッケージは最初にグループにしましょう。

Import Blank

import _ "pkg" はメインパッケージかテストのみで使用しよう

Import Dot

. を使用したインポートは循環参照によってパッケージの一部がテストできないときに使用しよう

In-Band Errors

Error 型か bool を返して、正しく取得できたか示す値を追加して返せ。 戻り値がエラーを表現しているか調べることを求めるな。

// Lookup returns the value for key or ok=false if there is no mapping for key.
func Lookup(key string) (value string, ok bool)

Indent Error Flow

エラーハンドリングの分岐を最小にしよう。

if err != nil {
    // error handling
    return // or continue, etc.
}
// normal code

Initialisms

URLURLurl にしよう。
Url にしてはいけない。
同様に appId ではなく、appID にするべき。
ただし、protobuf のコンパイラによって生成されたコードは例外。

Interfaces

モックのためにAPIの実装側にインターフェースを定義してはいけません。
替わりに実際に実装された公開APIからテストできるようなAPIを設計しましょう
使われる前にインターフェースを定義してはいけない。

Line Length

1行を短く保ちたいがために無理に改行を入れる必要はない。
行の意味によって改行するべき。

Mixed Caps

公開しない定数は maxLength にしよう。

Named Result Parameters

関数内で戻り値のための変数を宣言するのを省略したいがために名前付き戻り値を使うのはやめましょう。

この例よりも

func (f *Foo) Location() (float64, float64, error)

こっちのほうがわかりやすい。

// Location returns f's latitude and longitude.
// Negative values mean south and west, respectively.
func (f *Foo) Location() (lat, long float64, err error)

Naked Returns

変数なしの return 文は、関数定義で宣言した変数の値を返します。

Package Comments

Godocのパッケージのコメントはパッケージ節の前に空行無しで書かなくてはいけない。

// Package math provides basic constants and mathematical functions.
package math

Godocのコメントは公開されるものなので、正しい英語で書け。   先頭は大文字にしろ。

Package Names

chubby というパッケージの中で ChubbyFile という名前にすると、呼び出すときに chubby.ChubbyFile となるので、避けましょう。
chubby.Fileなどにしよう。

Pass Values

たかだか数バイトを節約するために引数にポインタを指定するのは辞めましょう。
ただし、大きなStructや今後大きくなりそうなものはこれに限らない。

Receiver Names

レシーバ名は大抵1〜2文字で足りる。
Client であれば、 me とか this とかではなく、c とか cl にしよう。
レシーバー名は統一しよう。

Receiver Type

  • レシーバが map, func, channel ならポインタを使うな
  • メソッドが値を変更するなら ポインタ一択
  • sync.Mutex などの sync 系は ポインタ一択
  • レシーバが大きな構造体や配列ならポインタがよい
  • 値型の time.Timeint, string など基本的な型はレシーバが値の方がよい場合がある。プロファイルで確認する前にレシーバにするのはやめよう。
  • 迷っている場合はレシーバをポインタにしよう。
  • レシーバの型は統一しよう。

Synchronous Functions

非同期処理よりも同期処理を好む。
呼び出し側で別の goroutine から呼び出してあげよう。

Useful Test Failures

テストが失敗した時には、以下を伝えよう。

  • なにが悪かったのか
  • どんな入力があったか
  • 実際にどんな値が来たのか (got or actual)
  • どんな値が来ることを期待していたのか (want or expected)

Variable Names

Goでの変数名はより短くあるべき。
lineCount よりも c ですし、 lineIndex よりも i

参考リンク