Go言語の開発環境を設定する
以下の記事を参考に、Go言語の環境設定を行います。
Overview
- Go言語で書かれたコードは基本的には、一つのworkspaceに置かれます。
- workplaceは多くのrepoを持ちます。
- それぞれrepoは幾つかのpackegeを持ち合わせています。
- 一つのdirecoty内に1つ以上のGoソースコードがあります。
- packageのパスはimport pathで決められます。
Workspaces
workspaceは3つのdirecotriesを配下にしています。
- src
Go source fileが入っている。 - pkg
package objectが入っている - bin
実行コマンドが入っている。
file tree exampole:
bin/
hello # command executable
outyet # command executable
pkg/
linux_amd64/
github.com/golang/example/
stringutil.a # package object
src/
github.com/golang/example/
.git/ # Git repository metadata
hello/
hello.go # command source
outyet/
main.go # command source
main_test.go # test source
stringutil/
reverse.go # package source
reverse_test.go # test source
golang.org/x/image/
.git/ # Git repository metadata
bmp/
reader.go # package source
writer.go # package source
GOPATH environment variable
GOPATHの環境変数は、workplaceの場所になります。Unixでは
$HOME/go
がdefault 設定です。GOPATHはまた、Goのインストール場所とは同じ場所にはなりえないことに、注意が必要です。
設定方法としては、次のコマンドでdefaultのpathを確認して
$ go env GOPATH
pathのsubdirectoryにworkplace’s binを追加します
$ export PATH=$PATH:$(go env GOPATH)/bin
また、GOPATHにパスを通します。
$ export GOPATH=$(go env GOPATH)
Import paths
import pathはpackageを特定する、文字列になります。
独自のパッケージを使用する際は、標準ライブラリまたは他の外部ライブラリへの将来の追加と衝突する可能性の低い、baseパスを選択する必要があります。
コードをソースリポジトリのどこかに置いておくと、そのソースリポジトリのルートをベースパスとして使用する必要があります。
たとえば、github.com/userにGitHubアカウントがある場合、そのパスがベースパスになります。
今回は下記のように、github.com/userをbase pathに設定していきます。
$ mkdir -p $GOPATH/src/github.com/user
goでhello word!
ます、package pathを選び、それに合わせたpackage direcotryを作ります。
$ mkdir $GOPATH/src/github.com/user/hello
hello directory内にhello.goをつくります。
hello.go
package main
import "fmt"
func main() {
fmt.Printf("Hello, world.\n")
}
次に上のプログラムをinstall/buildします。
$ go install github.com/user/hello
go toolはエラーが起きたときのみ出力するので、上のコマンドに何も出力結果が現れない時、helloコマンドはbuildされたことになります。
なのでbinary nameを呼ぶと、以下のようになります。
$ hello
Hello, world.
git等を使う場合は、以下の様に設定します。
$ cd $GOPATH/src/github.com/user/hello
$ git init
Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/
$ git add hello.go
$ git commit -m "initial commit"
[master (root-commit) 0b4507d] initial commit
1 file changed, 1 insertion(+)
create mode 100644 hello.go
次に、libraryを作ります
まず、パッケージのパスを決めて、該当するdirectoryを作ります。
$ mkdir $GOPATH/src/github.com/user/stringutil
このdirectory内にreverse.goを次のように書きます。
reverse.go
// Package stringutil contains utility functions for working with strings.
package stringutil
// Reverse returns its argument string reversed rune-wise left to right.
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
そして、次のコマンドでcompileします。
$ go build
buildができたら、先程のhello.goを次のコードに置き換えます。
package main
import (
"fmt"
"github.com/user/stringutil"
)
func main() {
fmt.Printf(stringutil.Reverse("!oG ,olleH"))
}
go tooldはinstallするときは常に、そのdependenciesも含めてinstallを行ってpkgフォルダにpackage objectを作ります。今回は、hello.goをinstallして、stringutilパッケージも同時にinstallさせます。
$ go install github.com/user/hello
$ hello
Hello, Go!
Package names
GO言語で書かれるコードの最初のstatementは必ず、以下のようになります。
package name
nameにはpackageの名前が記されます。
また実行可能なコマンドには常に、 package main
が置かれます。
package名前が同じでも、import pathが違えば、それぞれを分けて使用することが可能になります。
Testing
_test.goで終わる名前のファイルを作成し、TestXXXという名前の関数にfunc(t * testing.T)という名前の関数が含まれているテストを作成します。 テストフレームワークは、このような各機能を実行します。 関数がt.Errorやt.Failなどの関数を呼び出すと、テストは失敗したものとみなされます。
では、実際にstringtil packageにテストファイルを置きます。テストファイルは、実行コードの隣に置きます。
reverse_test.go:
package stringutil
import "testing"
func TestReverse(t *testing.T) {
cases := []struct {
in, want string
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
}
for _, c := range cases {
got := Reverse(c.in)
if got != c.want {
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
}
}
}
すると、PASSした際の結果は次のように返ってきます。
stringutil $ go testPASSok github.com/user/stringutil 0.013s
Remote packages
go toolはgit pullのように、remote repositoryをfetchすることができます。
例えば、下期のコマンドを打ちます。
$ go get github.com/golang/example/hello
$ $GOPATH/bin/hello
Hello, Go examples!
また、packagesのimport pathにrepository pathを含めると、goは自動でfetch/build/installを行います。
指定されたパッケージがワークスペースに存在しない場合、getを実行すると、GOPATHで指定された最初のワークスペースの内側に配置されます。
(パッケージがすでに存在する場合は、get getはリモートフェッチをスキップし、go installと同じ動作をします)。
また、package内は以下のような構造になります。pkg/内に新しいstringtil packageがあることから、各パッケージを別々のものとして、inport することができます。
bin/
hello # command executable
pkg/
linux_amd64/
github.com/golang/example/
stringutil.a # package object
github.com/user/
stringutil.a # package object
src/
github.com/golang/example/
.git/ # Git repository metadata
hello/
hello.go # command source
stringutil/
reverse.go # package source
reverse_test.go # test source
github.com/user/
hello/
hello.go # command source
stringutil/
reverse.go # package source
reverse_test.go # test sourceimport "github.com/golang/example/stringutil"
これによって、外部のGo projectを簡単に取り込むことが可能になります。