Edited at

golangのループ変数の使い方をチェックするlinter作ってみた

More than 1 year has passed since last update.


動機

golangでforループを回すと、中でうっかりクロージャやリファレンスを取れません。


example/readme.go

package example

import "fmt"

func readme() {
values := []string{"a", "b", "c"}
var funcs []func()
for _, val := range values {
funcs = append(funcs, func() {
fmt.Println(val)
})
}
for _, f := range funcs {
f()
}
/*output:
c
c
c
*/

var copies []*string
for _, val := range values {
copies = append(copies, &val)
}
/*(in copies)
&"c"
&"c"
&"c"
*/

}


意外と気づきにくいバグの元になってプログラマは容易に死にます。

一応一部のケースは go vet でも検出できますが、万能ではありません。(なぜか go func(){ }() だけは気をつけてくれる)

ならチェックしようぜ!ということでlinter作りました。

scopelint


使い方

golint とほぼ同じです。

go get -u github.com/kyoh86/scopelint でインストールして、雑にパッケージとかディレクトリとかファイルを渡してください。

scopelint github.com/kyoh86/scopelint/example

scopelint ./...

幾つかオプションも用意しました。



  • --set-exit-status : golintに同じ。エラーがあれば終了コードを 1 に設定する。毎回指定するのアホらしいので、デフォルト true


  • --vendor : vendor ディレクトリの下は見ない。これもデフォルト true


  • --test : *_test.go なファイルは見ない。これもデフォry


終わりに

あちこち golint のソースをコピペして作っています。ライセンス書かなきゃ…

とまれ、良きgopherライフを!