失敗は一時の恥

パッケージソフト開発をしているプログラマが気の赴くままに何かを投稿するブログ.

Hello Golang!

How to Write Go Code の内容に沿ってコードを書いてみました.

概要

Go に興味があったのと,最近 Go で色々する必要が生じたので,とりあえずチュートリアルをやってみようといったところです.

僕自身 Go のプログラムを書いたことがほぼないという状態から,とりあえず Hello world 程度のものを動かすという内容です.

まだ勉強不足なので手を動かしながら疑問に思った点もひとまず書き散らしつつ,ひとまず読み進めた軌跡というような感じになっています.

最終的に書いたものは GitHub に置きました.

作業環境

大雑把に以下のような環境です:

Go のインストール

brew install go で入れます.

Go 自体のバージョン管理 (rbenv 的な) はどうするのかふと頭をよぎりますが,今の時点ではとりあえず気にしません.

ソースディレクトリを作る

適当に作業ディレクトリを決めて,ソース置き場を作ります.

How to Write Go Code に従えば,ディレクトリのつくりは

  • 作業場所を決める (そこを $GOPATH とする)
  • $GOPATH/src/github.com/username/project みたいなディレクトリにコードを置く
  • go コマンドによるビルド物は $GOPATH/bin に生成されるようになる

という風になっているようです.

$GOPATH は Go コマンドの動作に影響する環境変数で,デフォルトだと $HOME/go となるようなのですが, プロジェクト毎にライブラリなどを管理したい場合は都度都度指定した方がいいように想像しました.

Visual Studio Code の設定

テキストエディタだけでもできないことはないのでしょうが,作業効率的に IDE 的なものがあったほうがいいと思い,とりあえず VS Code を使っています. (Go 向けのもっといい IDE があるのかどうかは今の時点では気にしていません)

まず,Go の拡張機能を入れました.

GOPATH in the VS Code Go Extension の説明を参考に,GOPATH の推測を有効にするようにしました . (この設定をしないと VS Code がエラーを出したりして不安な気持ちになるのでとりあえずやっておいた方がいいと思います)

ワークスペースの設定 .vscode/settings.json に次のように記述します.

{
  "go.inferGopath": true
}

これを指定すると,

という動きをするようです.

コードを書く

前述の内容を実施しておけば,VS Code で作業ディレクトリ ($GOPATH となる場所) を開いて,How to Write Go Code の内容にしたがってコードを書いてコマンドを叩いて,という操作ができるようになっていると思います.

  • src/github.com/usrname/hello とか,
  • src/github.com/username/stringutil とか,

あたりに,言われた通りにとりあえずコードを写経しました.

パッケージ名について

Go のプログラムでは「パッケージ名」とは

  • プログラム全体でユニークである必要はない
  • ユニーク性が必要なのは Import path (e.g. github.com/username/project)
  • プログラム上のパッケージ名は Import path の最後の要素 (e.g. Import path がcrypto/rot13 ならパッケージ名は rot13)

という扱いのようです.

Java だとクラス名が衝突するときはプログラム上 FQCN で指定する (com.example.project.subproject.SomeClass みたいな) ことになっていたと思うのですが,Go でパッケージ名が衝突した時はどうなるのでしょう.Haskell みたいに import qualified できるといいな……

テスト

ユニットテスト書き方の説明に従って書いてみました.

テストを実行するときは,go test github.com/user/project といったコマンドを叩きます.

コード例 (テスト付き)

ふつうのテストとは別に,Example というコード例を記述する仕組みもあるみたいです. 関数名が Example で始まるものが go test コマンドによりコード例として認識されます.

今回のチュートリアルにはないのですが,次のような main 関数に対する Example を書いてみました.

package main

func ExampleMain() {
    main()
    // Output:
    // Hello world!
}

この // Output: に続けて書かれているコメント通りの文字列が標準出力に出るのかどうかが,go test コマンド実行時に検証されます

テストをまとめて実行

go test コマンドにパッケージ名のプレフィックス... を与えると,そのプレフィックスに一致するパッケージのテストがすべて実行されます.

こんな感じです:

$ go test github.com/snobutaka/hello-golang/...
ok      github.com/snobutaka/hello-golang/hello
ok      github.com/snobutaka/hello-golang/stringutil

リモートからのソース取得

go get github.com/golang/example/hello といったコマンドを叩くと,リモートからそのソースを取得して $GOPATH/src 以下に配置してくれます.

この go get をした時点で,$GOPATH/bin に生成される hello というバイナリが,自分で書いたサンプルコードをビルドしたものなのかリモートから取得してビルドしたものなのかよく分からないのですが,例としてどうなんでしょう……

ここまでやってみて

ひとまず,プロジェクトを構成して,コードを書いて,テストを書いて,実行して,という流れはイメージが持てたように思います.

まだまだ実践的なモノを作れそうなレベルにはないので,もっと色々調べなきゃですね.

さらに学ぶために

この辺のページも読んでみようと思いました:

あとはこのあたりの本も読んでみたい: