Gophercon 2018においてRuss Cox氏は、エラー処理、ジェネリックを含むGo 2について説明し、新しい提案がどのように見えるかのプレビューを提供した。

昨年のGophercon 2017の発表で、Go 2は、多くの相互作用する並行サービスで構成された大規模システムと、多くの緩やかに調整されたエンジニアによって開発された大規模なコードベースというシステムを大規模に開発するための効率的な言語であるという全体の目標を維持しながら、言語の欠点を修正する。

Cox氏が説明したように、Go開発のアンケートで一貫して表示される3つの領域がある: パッケージ管理、エラー処理、ジェネリック

InfoQのレポートでモジュールはGo 1.11で登場したが、また実験中に変更されている。モジュールは GOPATH の代わりとしてプロジェクトの依存関係を見つけるための代替手段として、共通のインポートパスプレフィックスを共有するパッケージの集合である。これはまた、再帰的な依存関係が満たされることを保証するためのバージョン管理のユニットである。

エラー処理についてCox氏は、Goの欠点であると認識していると話した。Goがエラー処理をするひとつの問題は、以下の寛容パターンに示すように、開発者にあまりに多くの定型文を強要していた:

value, err := DoSomething() if err != nil { log.Println(err) return err }

もうひとつの関連する問題は、Goがファイル名や行番号など、充分な詳細情報を呼び出し元に戻すことができるエラー処理モデルを明示的に育成しないことだ。そのような詳細情報を提供することは難しくないが、定型文に追加される。

これら全てを修正するために、Go 2のエラー処理のドラフトデザインでは、新しいパターンを提供する:

check f(...) 式は、明示的にそれを維持しながら文法的に端的にエラーチェックする

handle ステートメントは、checkステートメントが失敗した時に、一か所で正確なエラーレポートを簡単にする

check/handle の組み合わせにより、次のようにエラー処理が効率的に合理化される:

func OldErrorHandlingExample() { hex, err := ioutil.ReadAll(os.Stdin) if err != nil { log.Fatal(err) return fmt.Errorf("copy %s %s: %v", src, dst, err) } data, err := parseHexdump(string(hex)) if err != nil { log.Fatal(err) return fmt.Errorf("copy %s %s: %v", src, dst, err) } os.Stdout.Write(data) return nil } func NewErrorHandlingExample() { handle err { return fmt.Errorf("copy %s %s: %v", src, dst, err) } hex := check ioutil.ReadAll(os.Stdin) data := check parseHexdump(string(hex)) handle err { // Do something specific here, if required; e.g. // if you opened a file, close it } os.Stdout.Write(data) return nil }

handle ブロックは、語彙的に連鎖し、最も奥の内部から、returnステートメントを含む最初まで実行されることを考慮することが重要だ。

ジェネリックのコンセプトは、C++やJavaなど他の言語からGoコミュニティでも知られている。ジェネリックを言語に導入するときのひとつのキーポイントは、どのようにパラメタリック型を定義して、例えば等価性のように安全に制約する方法である。 制約をジェネリック仕様から除外する、つまり、実装から推測させることは、コード開発において、いとも簡単に破壊できる貧弱なインターフェイスを引き起こすとCox氏は言う。

現在のGo 2におけるジェネリックのドラフトデザインではパラメタリック型がサポートしなくてはならないオペレーターの定義に contract を使い、実装で使用できるようにする。例えば:

contract Equal(t T) { t == T } func Uniq(type T Equal)(in <-chan T) <-chan T { ... if v != n { ... } ... }

現時点のドラフトデザインは、ただのドラフトである。今はGoコミュニティに参加して、彼らの改善を助けることで、公式の提案を変えることができる時期である。Go 1の開発は止まらない。実際、元の計画によれば、Go 2の後方互換機能は、Go 1リリースの一部として段階的にリリースされ、モジュールサポートはすでにGo 1.11で行われており、その後、言語は既存のコードベースとの互換性を損なう機能を含めた変更が始まる。