Goらしいコードの書き方(ミニ)
Go 1.6 Release Party
17 February 2016
鵜飼文敏
Fumitoshi Ukai
Google Software Engineer - Chrome Infra team
鵜飼文敏
Fumitoshi Ukai
Google Software Engineer - Chrome Infra team
言語仕様の変更 -> なし!
Goらしいコードの書き方は基本的にかわっていない。
golang.org/doc/effective_go.html
github.com/golang/go/wiki/CodeReviewComments
Go is a new language. Although it borrows ideas from existing languages, it has unusual properties that make effective Go programs different in character from programs written in its relatives. A straightforward translation of a C++ or Java program into Go is unlikely to produce a satisfactory result -- Java programs are written in Java, not Go. On the other hand, thinking about the problem from a Go perspective could produce a successful but quite different program. In other words, to write Go well, it's important to understand its properties and idioms. It's also important to know the established conventions for programming in Go, such as naming, formatting, program construction, and so on, so that programs you write will be easy for other Go programmers to understand.
This document gives tips for writing clear, idiomatic Go code.
go spec (2008/05/02)
Effective Go first commit
commit 94439982b62dee7085aae289e4a6643debd69255 Author: Russ Cox <rsc@golang.org> Date: Thu Jun 25 09:38:35 2009 -0700 Effective Go; draft
Until public release (2009/11/10): 36
go1 (2012/03/28): 81
go1.1 (2013/05/13): 26
go1.2 (2013/11/29): 12
go1.3 (2014/06/19): 9
go1.4 (2014/12/11): 2
go1.5 (2015/08/19): 5
go1.6 (2016/02/17?): 0
Goらしいコードを書く時のポイント
Goのインタフェースはとても便利で、実装の詳細を特定することなしにAPIを定義できます。 パッケージの基本的な構成要素について、可能な箇所では常にインタフェースとして定義しておくようにしましょう。 そうすれば、後で多くのメリットを期待できます。
利用しやすいAPIを提供する -> yes!
Goのインタフェースはとても便利 -> yes!
実装の詳細を特定することなしにAPIを定義できる
-> Javaのinterfaceとかもそうでは?
Goのinterfaceが便利なところは、 あらかじめ定義しておく必要がない ところ
可能な箇所では常にインタフェースとして定義しておくように
-> Goではinterfaceは必要になった時に定義すればよい
APIの実装側
io.Reader Read([]byte) (int, error) fmt.Stringer String() string
APIの利用側
type ReadCloser interface { Reader Closer }
concrete type
var mu sync.Mutex var buf bytes.Buffer
interface
nil
)var r io.Reader r = &buf
コンカレントに動作するプログラムが簡単に書ける
とはいっても、正しく書くのはまだ難しい
chanを使う時に注意すべき点
chan receiverがいないのでchanにsendするところでブロック
非同期が簡単にできるといっても同期のほうが理解しやすい
非同期APIより同期API
package bufio type Scanner func (s *Scanner) Scan() bool func (s *Scanner) Bytes() []byte func (s *Scanner) Err() error package filepath func Walk(root string, walkFn WalkFunc) error type WalkFunc func(path string, info io.FileInfo, err error) error
chanをpackageを越えてあまり使わない
非同期にするにはAPIを使う側がgoroutine+chanで制御する
同期APIを実現するために必要なら実装内部でgoroutine+chanを使う
They're fun to play with, but don't overuse these ideas.
Always use the right tool for the job.
鵜飼文敏
Fumitoshi Ukai
Google Software Engineer - Chrome Infra team