Go 1.5 の変更点

間もなく Go 1.5 がリリースされるようなので、 release notes の原稿から気になる変更点をピックアップしてみました。

言語仕様

構造体をキーとした map リテラルの簡略化

構造体をキーとした map のリテラルを少し簡単に書けるようになります。たとえば、これまでは

1
2
3
4
5
m := map[Point]string{
Point{29.935523, 52.891566}: "Persepolis",
Point{-25.352594, 131.034361}: "Uluru",
Point{37.422455, -122.084306}: "Googleplex",
}

と書いていたものが、

1
2
3
4
5
m := map[Point]string{
{29.935523, 52.891566}: "Persepolis",
{-25.352594, 131.034361}: "Uluru",
{37.422455, -122.084306}: "Googleplex",
}

と書けるようになります。

実装

C のソースコードの削除

コンパイラとランタイムがすべて Go で書き換えられ、C のコードは排除されました。

ガベージコレクタ

GC 処理のアルゴリズム改善・スケジューリング改善・並列化により、レイテンシが劇的に小さくなります。アプリケーションの動きが完全に停止する “stop the world” の時間はほとんどの場合 10 ミリ秒以下に抑えられるようです。

ランタイム

GOMAXPROCS のデフォルト値が 1 からコア数になります。シングルスレッド前提で書かれているプログラムにはもしかすると影響が出るかもしれません。

ポート

darwin/arm, darwin/arm64 (iOS) と linux/arm64 がサポートされました。

ツール

コンパイラ・リンカ

6g, 8g などのコンパイラ・リンカはなくなり、go tool compile, go tool link などに置き換えられました。

新たなデフォルトコマンドの追加

go vet, go cover, go doc コマンドが標準で使えるようになりました。

  • vet はソースコードのバリデーションや静的解析をおこなうツールです。
  • cover はカバレッジを計算してくれるツールです。

vetcover はよく使っているので、標準で同梱されるようになると嬉しいですね。

Go コマンド

Internal package

Go でのアクセス制御はこれまで public か private しか指定できませんでした。 Go 1.4 で internal package という、パッケージプライベートを実現する機能が試験的に導入されましたが、この段階ではまだコアライブラリでしか利用できるようになっていませんでした。 Go 1.5 でこの機能がユーザライブラリにも開放されます。

具体的には、パッケージ名に internal が含まれている場合、同一のルートパッケージからのみ import できます。たとえば、 $GOPATH/src/mypkg/internal/foo というパッケージは、 $GOPATH/src/mypkg からのみ import できます。

細かい仕様はデザインドキュメントに記載されています。go1.4で追加されたinternal packageについて - Qiita の記事なども参考になります。

Verdoring

Verdoring 機能が実験的にサポートされました。これはどういうものかというと、たとえば

1
2
3
4
5
6
7
8
9
10
$GOPATH
| src/
| | github.com/constabulary/example-gsftp/
| | | cmd/
| | | | gsftp/
| | | | | main.go
| | | vendor/
| | | | github.com/pkg/sftp/
| | | | golang.org/x/crypto/ssh/
| | | | | agent/

というリポジトリ構成にしておくと、 github.com/constabulary/example-gsftp/cmd/gsftp/main.go において

1
2
3
4
5
6
import (
...
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"github.com/pkg/sftp"
)

と書けば verdor 以下の依存ライブラリを import できるようになります。 これまでは

1
2
3
4
5
6
import (
...
"github.com/constabulary/example-gsftp/vendor/golang.org/x/crypto/ssh"
"github.com/constabulary/example-gsftp/vendor/golang.org/x/crypto/ssh/agent"
"github.com/constabulary/example-gsftp/vendor/github.com/pkg/sftp"
)

というふうにフルパスを書かなければならなかったので、だいぶ楽になります。

ただしこの機能を有効にするには環境変数で GO15VENDOREXPERIMENT=1 と設定する必要があります。

これまで Go にはライブラリのバージョン指定機能がなかったため、たとえば依存関係解決ツールである Godep では Godep/_workspace/ で同じような機構を実現していました。 Go 1.5 からはこの標準機能を使っていくことになるでしょう。

標準ライブラリ

flag パッケージ

flag パッケージの help の表示が見やすくなりました。たとえば

1
cpuFlag = flag.Int("cpu", 1, "run `N` processes in parallel")

というフラグを定義すると、 help メッセージは

1
2
-cpu N
run N processes in parallel (default 1)

と表示されるようになります。 Go 1.4 までは

1
-cpu=1  run N processes in parallel

という表示だったので、少し見やすくなります。

math/big パッケージ

math/big パッケージに、任意精度の浮動小数点型である Float が追加されます。

reflect パッケージ

reflect パッケージに ArrayOfFuncOf 関数が追加されます。 SliceOf と同様に、実行時に配列や関数を表す型をつくることができるようになります。

感想

個人的な見どころはやはり GC の改善と internal package ですね。正式リリースが待ち遠しいです。