Go 1.13 と 1.14 (Go 2 へ向けて)

no extension

8月に正式リリースされる Go 1.13 の主な機能

Go 1.13 のベータ版が登場したようだ。 リリースノートも併せて公開されている。

Go 1.13 では数値のリテラル表現(2進数表現や浮動小数点数の16進数表現)など色々と重要な機能追加があるが,主なものは以下の通り。

errors パッケージへの機能追加

以前に紹介した golang.org/x/xerrors の機能が正式に errors パッケージに組み込まれるようだ。

golang.org/x/xerrors の機能をほぼ踏襲しているみたいなので,既に golang.org/x/xerrors を使っている人は僅かな変更で対応できるだろう。

環境変数 GO111MODULE の変更

環境変数 GO111MODULE の値が auto の際の挙動が変わるようだ。 具体的には

The GO111MODULE environment variable continues to default to auto, but the auto setting now activates the module-aware mode of the go command whenever the current working directory contains, or is below a directory containing, a go.mod file — even if the current directory is within GOPATH/src.

ということで GOPATH 以下にあるソースコードでも go.mod ファイルがあればモジュール対応モードで管理が可能なようだ。

GOPRIVATE, GOPROXY/GONOPROXY および GOSUMDB/GONOSUMDB

以前

を紹介したが,この機能を制御するために GOPRIVATE, GOPROXY/GONOPROXY および GOSUMDB/GONOSUMDB 各環境変数が追加される。

GOPROXY の既定値は https://proxy.golang.org,direct となっている。 これを無効にする場合は direct のみをセットすればよい。

ちなみに 1.13 からは go env コマンドが拡張され

$ go env -w GOPROXY=direct

という感じに設定できるらしい。 これでシステムの環境変数を汚さずに済む(笑)

GOSUMDB については

The new GOSUMDB environment variable identifies the name, and optionally the public key and server URL, of the database to consult for checksums of modules that are not yet listed in the main module’s go.sum file. If GOSUMDB does not include an explicit URL, the URL is chosen by probing the GOPROXY URLs for an endpoint indicating support for the checksum database, falling back to a direct connection to the named database if it is not supported by any proxy.

ということらしい。

また GOPRIVATE 環境変数を使えばミラーリングやチェックサム・データベースの対象から外すモジュールを指定できるようだ。

The new GOPRIVATE environment variable indicates module paths that are not publicly available. It serves as the default value for the lower-level GONOPROXY and GONOSUMDB variables, which provide finer-grained control over which modules are fetched via proxy and verified using the checksum database.

Google はミラーリング・サービスとして proxy.golang.org を,データベース・サービスとして sum.golang.org を提供しているが,個人的には

プライバシーに敵対的な企業のサービスだと思うとあまり利用したくない気分

なので

$ go env -w GOPROXY=direct
$ go env -w GOSUMDB=off

として無効にするのがいいかな。 まぁ,8月に正式版が出てから様子を見て方針を決めればいいか。

Go 1.14 へ向けて: try() 組み込み関数によるエラー検査

以下のブログ記事では Go 1.14 および最終的な Go 2 へ向けての方針が書かれている。

この中で注目したいのは Go 1.14 で追加されるというエラー検査機能だ。

エラーの検査については以前

において check 式(check expression)と handle 構文(handle statement)の提案を紹介したが,最終的には try() 組み込み関数を導入することにしたようだ。

具体的には

func foo() (T1, T2, ..., Tn, error) { ... }

という関数に対して

v1, v2, ..., vn := try(foo())

のように記述できる。 try() 組み込み関数は foo() 関数の返り値の error 値を見て nil でなければ値をセットして return する。 概念的にはこんな感じ

var err error
v1, v2, ..., vn, te := foo()
if te != nil {
    err = te
    return 
}

セットされた errordefer 構文で捕まえてまとめて処理できる。

func bar() (err error) {
    defer func() {
        if err != nil {
            fmt.Fprintln(os.Stderr, err)
        }
    }()

    v1, v2, ..., vn, := try(foo())
    ...
    return
}

実際のコードで考えてみよう。 たとえばファイルのコピーを行う関数 copyFile()

func copyFile(src, dst string) error {
    r, err := os.Open(src)
    if err != nil {
        return err
    }
    defer r.Close()

    w, err := os.Create(dst)
    if err != nil {
        return err
    }
    defer w.Close()

    if _, err := io.Copy(w, r); err != nil {
        return err
    }
    return nil
}

try() 組み込み関数と defer 構文を使って以下のように書き直せる。

func copyFile(src, dst string) (err error) {
    defer func() {
        if err != nil {
            err = fmt.Errorf("copyFile %s %s: %v", src, dst, err)
        }
    }()

    r := try(os.Open(src))
    defer r.Close()

    w := try(os.Create(dst))
    defer w.Close()

    try(io.Copy(w, r))
    return nil
}

try() 組み込み関数を導入することにより,演算子や構文を追加することなく後方互換性を確保しつつ仕様を拡張できるというのは大きい。 来年の冬が楽しみだなぁ。

ブックマーク

参考図書

photo
プログラミング言語Go
アラン・ドノバン (著), ブライアン・カーニハン (著), 柴田芳樹 (著)
丸善出版 2016-06-20 (Release 2021-07-13)
Kindle版
B099928SJD (ASIN)
評価     

Kindle 版出た! 一部内容が古びてしまったが,この本は Go 言語の教科書と言ってもいいだろう。感想はこちら

reviewed by Spiegel on 2021-05-22 (powered by PA-APIv5)