Go でこれどうやるの? 入門
2017-10-17 @zaru
@zaru
話したいこと
REPL
ブレークポイント
パッケージ管理
Hot reload
テストコード
パッケージ・バイナリ配布gem
REPL
Read-eval-print loop の略。Ruby だと irb や pry 、PHPだと psysh の
こと。これがないと構文のチェックとか、これってどう動くのっていう
確認がやりにくい。
Go では gore がデファクトスタンダード(?)
インストール
go get -u github.com/motemen/gore
# 以下はオプションだが、あったほうが良い
go get -u github.com/nsf/gocode
go get -u github.com/k0kubun/pp
go get -u golang.org/x/tools/cmd/godoc
必要なパッケージを勝手にimport してくれるオプションを付与して
gore を起動。あとは自由にGoコードを書く。
gore -autoimport
よく使うgore コマンド。
:doc <パッケージ名>
指定パッケージや関数のドキュメントが見られる
autoimport にしている場合、一度実行しないと見られない
:print
gore で生成しているコードが見られる
ブレークポイント
Ruby でブレークポイントというと binding.pry 。 Go のブレークポイン
トは go-pry というライブラリがある。
インストール
go get -u github.com/d4l3k/go-pry
使い方
止めたい場所に pry.Pry() を仕込む。
package main
import "github.com/d4l3k/go-pry/pry"
func main() {
a := 1
pry.Pry()
}
go run ではなく go-pry run で動かす。
go-pry run main.go
そうすると、止まってREPL チックにコードを実行できる。ただし、
Echo では動かない。フレームワークやコードによっては動かないので
注意。
Echo の場合は delve を使う。IntelliJ やVSCode は内部的にこれを利用
している模様。
IntelliJ のブレークポイントは変数の中身を見ることはできるが、
binding.pry のようにREPL チックに自由にコードを書いて実行するこ
とはできない。
ちょっとしたコードや、CLIツール系なら go-pry でガッツリデバッグ。
日常的にはIntelliJ というノリ。
IntelliJ ブレークポイントビルド
パッケージ管理
Ruby だと bundler 。Go では dep 。 glide も有名だが、 dep が公式なの
でこちらを利用していく。
go get -u github.com/golang/dep/cmd/dep
dep init
パッケージはvendor ディレクトリ以下にダウンロードされる。
dep ensure
Gopkg.lock にRevision などが記録される。
パッケージのアップデートはオプションコマンドで。
dep ensure -update
dep ensure -update パッケージ名
なお、 dep などのバージョン管理ツールを利用しないと、バージョン
指定をしてライブラリを利用するということはできないので注意。 Go
的には常に最新のMaster を利用してくれよな! 公開パッケージを作
る人は常に後方互換性を保ってくれよな! というスタンスっぽい。
参考How should I manage package versions using "go get"?
ホットリロード
Ruby では気にする必要はなかったが、都度ビルドする必要があるGo
ではファイルウォッチャー的なツールが必要になる。個人的には
realize が簡単で使いやすい。
go get -u github.com/tockins/realize
realize run
これだけ。
テスト
テストはGo 標準でサポートしている。
ファイル名に _test.go を付ける
関数名は TextXxx でXxx は対象関数名
testing.T 構造体に含まれる関数を使う
Error テストケース失敗、継続実行
Fatal テストケース失敗、終了
Log ログ出力
assert などは公式では用意されていない
go test で実行
印象は愚直。assert がないから温かみを感じる手書き感。しかしそれ
が、逆に誰が見ても理解できるテストコードになるのかもしれない。冗
長な雰囲気あるけど、それはGo ならでは。
エラーメッセージは、何が落ちたか(What)というよりも、何で落ち
たか(Why)を重視して書くのが良さげ。
参照Why does Go not have assertions?
サンプルテストコード
package main
import (
"testing"
)
func TestSum(t *testing.T) {
actual := Sum(10, 20)
expected := 30
if actual != expected {
t.Errorf("got %vnwant %v", actual, expected)
}
}
参照Go のTest に対する考え方
パッケージ・バイナリ配布
goreleaser を使うととても便利。
go get -u github.com/goreleaser/goreleaser
.goreleaser.yml
builds:
- binary: container-builder-local-api
goos:
- windows
- darwin
- linux
goarch:
- amd64
- 386
archive:
format: zip
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
files:
- README.md
release:
github:
owner: zaru
name: container-builder-local-api
GitHub releases へ反映
GitHub releases にバイナリをアップロードするにはAPI TOKEN が必
要になる。Personal access token を発行する。
export GITHUB_TOKEN=`YOUR_TOKEN`
git tag -a v0.1.0
git push origin v0.1.0
goreleaser

Goでこれどうやるの? 入門