Goチームは、ジェネリック、ファジング、ワークスペース、パフォーマンス向上をサポートするGo 1.18のリリースを発表した。
Go 1.18によって提供されるジェネリックスの実装は、型パラメーターの提案に沿っている。この実装によって、開発者はオプションの型パラメーターを型と関数の宣言に追加できるようになる。InfoQは、Go 1.18ベータ1で初めて利用できるようになったときに、Goのジェネリックの基本構文を記事にしていた。簡単に言うと、ジェネリックmap
で機能する関数を定義する方法は次のとおりである。
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
この関数を呼び出すときは、オプションで型引数を省略できる。
SumIntsOrFloats[string, int64](arg)
SumIntsOrFloats(arg)
現在のジェネリック設計はいくつかのユースケースのみをサポートしている。そのユースケースは「大多数のユーザ」のニーズに対応する。Goチームは、ジェネリックスに対する取り組みを継続して、将来のリリースでより高度なユースケースをサポートする予定である。Michael Ernst氏が指摘しているように、コードのクリーンさと明快さを犠牲にして、現在の制限のいくつかを回避することができる。
1.18のGoジェネリックは安定版と考えられているが、Goチームは、実装レベルだけでなく、設計と仕様においてもバグの可能性があることを無視できない。
言語に対するこれらの新しい変更には、本番環境での重要なテストが行われていない大量の新たなコードが必要となりました。これは、より多くの人がジェネリックコードを記述して使うときにのみテストされるものです。
チームはまた、不整合が見つかった場合に、将来のGoリリースで重大な変更が必要となる可能性があることを明らかにしている。つまり、バグの動きとして機能としていたジェネリックを使用するプログラムは、バグが修正された後に、そのようには動作しなくなる。
Goジェネリック構文のクイックスタートについては、公式のジェネリックチュートリアルを確認してください。タイプパラメータの提案によって、これまでとは違い、ジェネリックによって設計で何ができるかを示す完全なビューが提供され、また、いくつかの使用例が提供されるようになった。この機能の詳細については、言語仕様を参照してください。
Go 1.18は、ファジングも安定板としてサポートする。これは、入力を継続的に操作するテストを自動的に生成することで、発見できていないバグを見つけることを目的とした手法である。ファジングは、セキュリティテストに特に役立つが、排他的ではない。
マルチモジュールワークスペースは、複数のモジュールを同時に管理しやすくすることを目的としている。go
コマンドは、ユーザが編集できる唯一の「main」モジュールと認識するため、開発者がモジュールに新しいインターフェイスを追加して、同じプログラムに属する別のモジュールで使用することは困難であった。gopls
コマンドは、スーパーモジュールを自動的に作成することでこれを改善する試みであった。これには、gopls
コマンドとgo
コマンドで使用されるバージョンの間に不一致が生じるという欠点があった。ワークスペースでは、すべての問題に対処する必要があるモジュール処理を総点検できる。
最後に、Go 1.18ではコンパイラのパフォーマンスも向上している。Go 1.17のレジスタABI呼び出し規約がこれらのアーキテクチャに拡張されたため、Apple M1、ARM64、PowerPC64が20%向上している。