Edited at

Goで使うべきでない文法 - from:GothamGo 2018 - Things in Go I Never Use by Mat Ryer -


概要

この記事は、2018年のGothamGoのMat Ryerさんのtalkの動画のサマリーになります

GothamGo 2018 - Things in Go I Never Use by Mat Ryer

この動画では、主に、「Goで可読性の高いコードを書く上で使わない文法」について具体的なポイントを挙げて話しているので、それらのまとめとなります。


まとめ


elseはできるだけ使わない

Goでは、Happy Path(正常系)は左端に寄せて(関数内でインデントをしない)で書いて、エラーハンドリングなどのその他のケースのみインデントするという書き方が好ましいとされている。

なので、異常系のみ都度if節で処理して、正常系はネストの中には入れないようにする。

そうすると、必然的にelseを使わないといけないケースは限られてくる。

動画内でも紹介されているリンク: Code: Align the happy path to the left edge

// bad 

if ok {
err := something()
if err != nil {
return errors.Wrap(err, "something")
}
// do more great things
} else {
return errors.New("not ok")
}

// good
if !ok {
return errors.New("not ok")
}
err := something()
if err != nil {
return errors.Wrap(err, "something")
}
// do more great things


labelは使わない

処理の流れが把握しづらくなるため。


gotoは使わない

処理の流れが把握しづらくなるため。


arrayは使わない

slice を使えばメモリの細かい挙動を考えずに複数のarrayを内部で作ってくれるので、厳密なメモリ最適化をしたい場合でもなければ、slice で事足りる。


newは使わない

&type{}みたいに直接オブジェクトを初期化すれば事足りる。


panicはそのままでは使わない

errorを使う。

ただし、下記のように、既存のpanicをカスタマイズして使う場合は有意義なものとなる。


func (t *Greeter) Greet1(name string) {
// Speakerがnilの場合に、下記の既存のpanicが起きる
// "invalid memory address or nil pointer dereference"
return t.Speaker.Speak("hello" + name)
}

func (t *Greeter) Greet2(name string) {
if t.Speaker == nil {
panic("greeter: cannot call Greet with nil Speaker")
}
return t.Speaker.Speak("hello" + name)
}


Structを初期化するときはfield名も明示する

それぞれの値がなにを表すのかわかりづらいため。

// bad

// どっちが緯度でどっちが経度かわからない
pos := &Position{40.712772, -74.006058}

// good
pos := &Position{
latitude: 40.712772,
longitude: -74.006058,
}


冗長なレシーバ付き関数の呼び出しはしない

type Greeter struct {

Format string
}

func (g Greeter) Greet(name string) { fmt.Println("hello", name) }

func main() {
g := Greeter{}
Greeter.Greet(g, "Mat") // bad

g.Greet("Mat") // good

}


最後に

さっと振り返れる用にまとめとして書いたもののこの動画自体そこまで長くなく、また前半では「そもそもGoにおける良いコードとは」という話もしており、冗談も交えつつで話も面白いので、もし英語に抵抗がなければ動画を全部実際に見てみることをおすすめします。