はじめに
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
URL
は URL
か url
にしよう。
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.Time
やint
,string
など基本的な型はレシーバが値の方がよい場合がある。プロファイルで確認する前にレシーバにするのはやめよう。 - 迷っている場合はレシーバをポインタにしよう。
- レシーバの型は統一しよう。
Synchronous Functions
非同期処理よりも同期処理を好む。
呼び出し側で別の goroutine から呼び出してあげよう。
Useful Test Failures
テストが失敗した時には、以下を伝えよう。
- なにが悪かったのか
- どんな入力があったか
- 実際にどんな値が来たのか (got or actual)
- どんな値が来ることを期待していたのか (want or expected)
Variable Names
Goでの変数名はより短くあるべき。
lineCount
よりも c
ですし、 lineIndex
よりも i
。