post Image
go1.7 の気になるところを試した

go1.7のbeta1がでたので、軽く個人的に気になるところを触ったメモ
以下、環境はOSXで、公式で配布されている go1.7beta1.darwin-amd64.tar.gz を使っています

目玉としては、生成されるバイナリの高速化や、GCの改善などがありますが、日常業務でそんなにGoのパフォーマンスに不満をもつ機会もないので、それ以外で気になったものを中心に試しました。

リリース予定は、順調にいけば8月です。

関連リンク

ダウンロード
https://golang.org/dl/#go1.7beta1

リリースノート
https://tip.golang.org/doc/go1.7

ビルドスピード

比較に使ったのは、仕事で使っているコードベースのビルド
generateされたコードも含めて、13万行ほどです。

go1.6

> /usr/bin/time -p go build cmd/tuner_server/main.go
real        18.80
user        30.14
sys          2.76

go1.7 beta-1

> /usr/bin/time -lp go build cmd/tuner_server/main.go
real        17.39
user        39.76
sys          4.32

ちょっと遅くなった… コードベースが大きいので、ほぼIOのスピードな感じはする。

ちなみに、バイナリサイズは、

version time
go1.6.1 35M
go1.7 beta-1 27M

かなりスリムになりました!

context パッケージ

今まで、 golang.org/x/net/context 配下 にあった、 context パッケージが、go 本体ライブラリに統合された。
context パッケージの役割については、Goの並行パターン:コンテキスト (Go Concurrency Pattern: Context) などを参照。

それと同時に、 *http.RequestContext() context.Context メソッドと、 WithContext(context.Context) *http.Request メソッドが追加された。

今まで、いろいろなフレームワークが、主にミドルウェアから各ハンドラへの情報の引き渡しのために、独自のコンテキスト構造を持っていたが、1.7からはデフォルトのcontextを使うことで、ミドルウェアの型を、func(http.Handler) http.Handler に統一できてすっきりする。
今までは各フレームワーク感で型が統一されてないので、ミドルウェアの再利用性が低かったけど、 nodeの connect みたいなミドルウェアを集めたパッケージがいろいろと出てくるんじゃないかと思われし、各種フレームワークも context パッケージを使うように落ち着くんじゃないかなぁと個人的には思っている。

context の使い方サンプル

package main

import (
    "context"
    "fmt"
    "net"
    "net/http"
    "net/http/httptest"
)

var middlewareKey = "m"

func middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
        ctx = context.WithValue(ctx, middlewareKey, "string set in middleware")
        cr := r.WithContext(ctx)
        next.ServeHTTP(w, cr)
    })
}

func main() {
    handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()

        // デフォルトで context に紐付いている値たち

        // サーバーがlistenしてるアドレス
        _ = ctx.Value(http.LocalAddrContextKey).(net.Addr)
        // サーバー自体のオブジェクト
        _ = ctx.Value(http.ServerContextKey).(*http.Server)

        // ミドルウェアでリクエストに関連付けた値を取得する
        fmt.Println(ctx.Value(middlewareKey))
    })

    ts := httptest.NewServer(middleware(handler))
    defer ts.Close()

    http.Get(ts.URL)
}

テストの subset 機能

テストの、サブセット機能がサポートされた

package main

import "testing"

func TestMain(t *testing.T) {
    t.Parallel()

    t.Run("Sub1", func(t *testing.T) {
        t.Run("SubA", func(t *testing.T) {
        })
        t.Run("SubB", func(t *testing.T) {
        })
    })
    t.Run("Sub2", func(t *testing.T) {
        t.Run("SubA", func(t *testing.T) {
        })
        t.Run("SubB", func(t *testing.T) {
        })
    })
}

のようなテストを書き go test -v すると

=== RUN   TestMain
=== RUN   TestMain/Sub1
=== RUN   TestMain/Sub1/SubA
=== RUN   TestMain/Sub1/SubB
=== RUN   TestMain/Sub2
=== RUN   TestMain/Sub2/SubA
=== RUN   TestMain/Sub2/SubB
--- PASS: TestMain (0.00s)
    --- PASS: TestMain/Sub1 (0.00s)
        --- PASS: TestMain/Sub1/SubA (0.00s)
        --- PASS: TestMain/Sub1/SubB (0.00s)
    --- PASS: TestMain/Sub2 (0.00s)
        --- PASS: TestMain/Sub2/SubA (0.00s)
        --- PASS: TestMain/Sub2/SubB (0.00s)
PASS
ok      /path-to-package  0.008s

のようになる

-run オプションの指定

Goのテストは、-run オプションで正規表現にマッチしたもののみ実行できるが、このオプションをsubsetになっているテストにも適用できる。
指定する場合は、階層毎に、/ で区切り、正規表現で指定する。
上の例だと以下の様な感じ。

2階層目が Sub2 のものだけ実行

> go test -v -run .*/Sub2
=== RUN   TestMain
=== RUN   TestMain/Sub2
=== RUN   TestMain/Sub2/SubA
=== RUN   TestMain/Sub2/SubB
--- PASS: TestMain (0.00s)
    --- PASS: TestMain/Sub2 (0.00s)
        --- PASS: TestMain/Sub2/SubA (0.00s)
        --- PASS: TestMain/Sub2/SubB (0.00s)
PASS
ok      /path-to-package   0.008s

3階層目が SubB のものだけ実行

> go test -v -run .*/.*/SubB
=== RUN   TestMain
=== RUN   TestMain/Sub1
=== RUN   TestMain/Sub1/SubB
=== RUN   TestMain/Sub2
=== RUN   TestMain/Sub2/SubB
--- PASS: TestMain (0.00s)
    --- PASS: TestMain/Sub1 (0.00s)
        --- PASS: TestMain/Sub1/SubB (0.00s)
    --- PASS: TestMain/Sub2 (0.00s)
        --- PASS: TestMain/Sub2/SubB (0.00s)
PASS
ok      /path-to-package   0.007s

テストの構造化と、ピンポイントで走らせてサイクルを回すのがやりやすくなりそう。


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。