golang.tokyo #14 に参加してきたのでその内容メモ。
発表内容は以下。
- ホリネズミでもわかる Goroutine 入門 by @inukirom さん
- チャネルのしくみ by @knsh14 さん
- ライトニングトーク 3 つ
- vgo の話 by @tanksuzuki さん
- プロダクションに Go を適用した話 by @kurikazu さん
- linter を作る話
例によって軽食 (と言いつつかなり十分な量の食事が) 提供されており、ありがたくいただきました…!
ありがとうございました。ごちそうさまでした。
ホリネズミでもわかる Goroutine 入門 by @inukirom さん
goroutine と chan の基本的な使い方
goroutine と defer と panic を組み合わせて使う場合に注意すべき点があり、
たとえば以下のような場合、A 内で張った defer は呼び出されない場合がある。
(スライド内では"呼び出されない"と書かれているが、その限りではなさそうな)
func A() {
defer func(){}()
go B()
}
func B() {
panic("panic!!")
}
状況としては、
A()
が終わるよりも先にB()
内のpanic
が先に実行されたときは、A()
内のdefer
は呼び出されないまま終わる。panic
よりもA()
が終了するほうが先なのであれば、defer
は実行される。
channel
channel については以下のような話題がとりあげられた。
- close は結構デリケート (使い方を誤るとすぐに動かなくなる) なので注意
- RW、R only、W only という属性を持たせられる
- select. default で non-blocking にできる
ところで、channel は close しないでほっとくような例もよく見るのであれが、close しなくて良いのだろうか?
golang-nuts でのやりとり を見るにつけては、 使われなくなった channel は GC の対象になるため、あえて明示的に close する必要はないと言っている気がする。 channel を close すると受け手側にお知らせがいくので、どうやらそういう目的で使うらしい。
wait 処理
goroutine の終了を待ち合わせする例の紹介。
- channel で待つ
- 単なるお知らせであってお知らせ内容に意味がないのであれば、
struct{}{}
を使うのがメモリ効率が良い。
- 単なるお知らせであってお知らせ内容に意味がないのであれば、
- sync.WaitGroup
sync.WaitGroup
で、複数の goroutine を待ち合わせしやすくなるsync.WaitGroup
にエラー処理を生やしたみたいなerrgroup
なんかもある
for ループと goroutine
for 文の中で goroutine 立てる例。よくある罠。
- 引数に渡して何とかする例
- 競合の解決
- 直列でええやん、という場合もある
- 排他制御に
sync.Mutex
使う例。RWMutex
もあるぞ sync/atomic
というパッケージもあるぞ
goroutine のリーク
- goroutine の中でブロックしちゃうと goroutine がリークする
context.Context
等を用いると goroutine を終わらせる処理を書きやすい
便利ツールの紹介
- gotrace
- goroutine と channel のやりとりを可視化できるぞ…!
- docker image を使って動かしている
チャネルのしくみ by @knsh14 さん
以下、LT
vgo by @tanksuzuki さん
vgo に関してはまだ使うのしんどい一面もあるものの、GOPATH、vendor が不要になるみたいな、Go を紹介するときに割と不評を買うところが改善されていくわけであり、今後に大いに期待である。
プロダクションに Go を適用した話 by @kurikazu さん
linter を作る話 by @dice_zu さん
プロジェクト独自のコーディングルールとかがあるのであれば、チームで lint を作って運用するのもありかもしれない。
個人的には named return value 禁止とかやりたいところであるが…?