プログラマブログ

by wacul

menu

2014.08.22これからGoを始める人のためのTips集

こんにちわ。最近業務でGoを書いているのですが、3,4週間たち、だいぶ環境にも慣れてきたので、これからGoを初めようと思っている人向けにTipsを書きたいと思います。

間違いや改善点などあれば、 @tutuming まで教えていただけると大変ありがたいです。

インストール と設定 (OSX)

http://golang.org/dl/ から、インストーラー (go1.3.1.darwin-amd64-osx10.8.pkg など) を選んで最新版をインストールしたら大丈夫です。自分の環境にあわせたインストーラ選んでください。

homebrewを使っている人は

1
brew install go

でもインストールできます。

$GOPATH とプロジェクトの作り方

Go のパッケージ管理には、 go get コマンドを使います。
go get github.com/aaa/bbb とすると、 github.com/aaa/bbb で公開されているgoライブラリまたは、実行ファイルがローカルにダウンロードされます。

インストール後、なにも設定せずに、 go get hogehoge すると、

1
package github.com/davecgh/go-spew/spew: cannot download, $GOPATH not set. For more details see: go help gopath

というエラーで怒られると思います。 GOPATH を設定しろと言っていますね。
これをどこに設定するか少し迷うと思います。

$GOPATH の2つの役割

GOPATH には2つ役割があります。

  1. ビルド時のインポートパスとして、GOPATH に指定したすべてのディレクトリを参照する(コロン区切り)
  2. go get コマンドで外部パッケージを読み込んだ時、 GOPATH の先頭のディレクトリにダウンロードする

そして、公式ドキュメントにもありますが、Goで自分のプロジェクトを書く時にも、このGOPATHの下で書くのが良いとされています。 例えば、自分が githubでソースコードを管理していて、ユーザー名が foo、リポジトリが bar だったら $GOPATH/src/github.com/foo/bar というディレクトリを作ってそこで作業します。

ここで、GOPATHに一つのディレクトリを指定して作業してしまうと、サードパーティのライブラリと、自分の作ったソースコードが混ざってしまって煩雑です。

1, 2 の性質を考慮して、GOPATHを複数指定し

1
2
export GOPATH=$HOME/go/third-party:$HOME/go/my-project
export PATH=$HOME/go/third-party/bin:$HOME/go/my-project/bin:$PATH # binをPATHに追加するのも忘れずに

などとしておけば、go get でインストールしたライブラリは、 ~/go/third-party にインストールし、自分のプロジェクトは、 ~/go/my-project の下で管理できます。

僕はいまのところこのやり方がしっくりきています。

参考: http://golang.org/doc/code.html

go-fmt を使おう

goには、gofmt という、ソースコードをコード規約に沿った形に整形するコマンドがついています。 エディタの設定で、保存時に自動で走らせるようにしておくと良いです。

このgofmtコマンドには、-rオプションという、ソースコードをパターンで書き換えるコマンドが用意されています。プロジェクト内の全部の関数名を変えたいときなど、リファクタリングに便利です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -d オプションで、diffを表示してくれる
$ gofmt -d -r 'Zen2han -> Zen2Han' .
diff util/util.go gofmt/util/util.go
--- /var/folders/cy/nds3c8y97nsb8p6l416w5__w0000gn/T/gofmt327353297     2014-08-14 19:29:31.000000000 +0900
+++ /var/folders/cy/nds3c8y97nsb8p6l416w5__w0000gn/T/gofmt979152124     2014-08-14 19:29:31.000000000 +0900
@@ -24,7 +24,7 @@
 }

 // 全角英数字を半角に変換する
-func Zen2han(src string) string {
+func Zen2Han(src string) string {
        retbuf := make([]rune, 0, utf8.RuneCountInString(src))
        for _, ch := range src {
                if ch >= 0xFF21 && ch <= 0xFF3A {
@@ -60,5 +60,5 @@
 }

 func NormalizeStr(src string) string {
-       return Hiragana2Katakana(Zen2han(src))
+       return Hiragana2Katakana(Zen2Han(src))
 }

# 実際に書き換えるには、 -w オプション
$ gofmt -w -r 'Zen2han -> Zen2Han' .

参考: https://golang.org/cmd/gofmt/

その他、開発に便利なライブラリ

go-spew

https://github.com/davecgh/go-spew

標準パッケージのfmt.Printf 関数でも %v で構造体の中身を覗けるのですが、オブジェクトがインデントされずに1行に収まり、中身を確認しづらいです。 go-spew を使うと、もうちょっといいかんじにフォーマットしてくれます(pythonのpprintみたいな感じ)。

サンプル

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import (
  "fmt"

  "github.com/davecgh/go-spew/spew"
)

func main() {
  a := struct {
      A []string
      n int
  }{
      A: []string{"a", "b", "c"},
      n: 123,
  }

  fmt.Println("--- fmt.Printf ---")
  fmt.Printf("%#v\n", a)
  fmt.Println("--- spew.Dump ---")
  spew.Dump(a)
}

実行結果

1
2
3
4
5
6
7
8
9
10
11
--- fmt.Printf ---
struct { A []string; n int }{A:[]string{"a", "b", "c"}, n:123}
--- spew.Dump ---
(struct { A []string; n int }) {
 A: ([]string) (len=3 cap=3) {
  (string) (len=1) "a",
  (string) (len=1) "b",
  (string) (len=1) "c"
 },
 n: (int) 123
}

goconvey

http://goconvey.co/ github: https://github.com/smartystreets/goconvey

BDD支援ライブラリですが、goconvey コマンドを起動しておくと、ファイルの更新を検知して、ブラウザでテスト結果を出力してくれます。

ブラウザでの結果確認自体は、goconveyを使ってテストを書かなくても使えるので、プロジェクトの途中からでも導入しやすいですね。

まとめ: Go楽しいです

まだ色々と試行錯誤中ですが、Go楽しいですので、やりましょう。

この記事を書いた人tutuming

株式会社ワカルの技術責任者です。フロントエンドからバックエンドまで、ひと通りやってます。最近の興味はチームづくりと、パンづくりです。

waculでは、プログラマを募集しています。

現在はプロダクトとして、課題発見から改善提案まで自動で行うWeb改善プラットフォーム「AIアナリスト」を開発中です。

waculの採用情報へ

ページトップへ