BackEnd

Go 1.18で追加されるGenericsの紹介

投稿日:2022年2月7日 更新日:

はじめに

まもなくリリース予定(2022年2月)のGo 1.18では、待望?のGenericsが導入されます。そこで、現在利用できるGo 1.18beta1で、Genericsの使い方を紹介します。

GoのGenerics

まず始めに、現時点でのGenericsの仕様や制限について紹介します。

Genericsの主な仕様

Genericsの主な仕様は以下のとおりです。

  • 関数や型宣言の構文に型パラメータが使えるようになった
  • パラメータ化された関数や型は、その後に[]で型引数のリストを記述することでインスタンス化することができる
  • インタフェース型の構文では、任意の型、union、T型要素を埋め込む事ができるようになった
  • any識別子(空のインタフェースのエイリアス)が追加された
  • comparable識別子(==や!=を使って比較できる全ての型の集合を表すインタフェース)が追加された

より詳しい言語仕様はproposalをご覧ください。

Genericsの制限

現在のGenericsの実装には以下の制限があります。

  • GoのコンパイラはGenerics関数やメソッドの内部での型宣言ができない(Go 1.19でサポートされる予定)
  • Goのコンパイラは予め宣言されたreal関数、imag関数、complex関数でのパラメータ型の引数を受け入れない(Go 1.19でサポートされる予定)
  • 型パラメータや型パラメータへのポインタを構造体の無名フィールドとして埋め込む事はできない。また、インタフェース型に型パラメータを埋め込む事もできない
  • 2つ以上の項を持つunion要素は、空でないメソッドセットをもつインタフェース型を含むことができない

Genericsを使ってみる

基本形

では、実際にGenericsを使ったメソッドを書いてみます。比較のために、まずはGenericsを使わない場合のメソッドを定義します。

int64型 のマップと float64型 のマップの合計値を返す2つの関数が定義されています。Genericsを使うと、これら2つの関数をまとめる事ができます。

SumIntFruits関数SumFloatFruits関数 のをまとめて、 SumFruits関数 を定義しました。この関数では、 comparable を満たす型のキーを持ち、 int64型 もしくは float64型 の値を持つマップを引数として受けとることができます。

型パラメータ(SumFruits関数のKやV)の制約は通常、型のセット(int64 | float64のように)を表しますが、コンパイル時には単一の型(呼び出し元のコードで渡している値の型)を表します。

なお、型パラメータとして許容していない、 int32型 の値を持つマップを引数として渡した場合、コンパイルエラーになります。

注意点として、型パラメータはGenericsコードがそのパラメータに対して実行する全ての操作をサポートしなければなりません。例えば、型パラメータに数値型が含まれているGenerics関数で文字列操作を実行しようとすると、コードはコンパイルされません。

呼び出しの際の型引数を省略する

多くの場合、呼び出し元のコードから型を推論することができるため、呼び出し時に型引数を省略することができます。先程のコードを修正すると、以下のようになります。

このように、 SumFruits関数 の呼び出し時に型引数を省略することができます。

型制約をインタフェースとして定義する

先程のコードでは、 V int64 | float64 のように冗長な記述になっています。そこで、これらを集約した型を定義することで、様々なところで利用できるようになるので、制約がより複雑になった場合などに、コードの効率化に役立ちます。

修正したコードは以下の通りです。

int64float64unionNumber と定義することで、よりコードがシンプルになります。

さいごに

Go 1.18で導入されるGenericsについて紹介しました。Generics自体は何年も前から議論されてしましたが、ついに導入されることとなり、実アプリケーションでGenericsの力を実感するのが楽しみです。

おすすめ書籍

エキスパートたちのGo言語 一流のコードから応用力を学ぶ Software Design plus 改訂2版 みんなのGo言語 Learning Go: An Idiomatic Approach to Real-World Go Programming

blog-page_footer_336




blog-page_footer_336




-BackEnd

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

Go言語

go:embedとGo 1.16、1.17での変更点まとめ

1 はじめに1.1 変更点一覧2 go:embedとは3 go:embedの使い方3.1 基本的な使い方3.2 複数のファイルを埋め込む3.3 異なるディレクトリのファイルを埋め込む3.4 ディレクト ...

【Git】マージコミットを消したい

1 はじめに2 例えばこんなことってないでしょうか?3 マージコミットを消す4 さいごに はじめに こんにちは、tonnyです。 今回はGitのケーススタディ的なものを書きたいと思います。 反面教師と ...

rails

Ruby、Railsの時間に関するメソッドを使用してみた

はじめに 普段PHPのお仕事をしています、tonnyです。 半年程前からRuby on Railsの勉強を始めました。 今回はよく使う時間に関するメソッドついてまとめたいと思います。 目次 1 はじめ ...

RubyのHanamiチュートリアルをやってみた

1 はじめに2 紹介2.1 Hanamiとは?2.2 Hanamiを選ぶ理由2.2.1 軽量2.2.2 アーキテクチャとして2.2.3 スレッドセーフ3 チュートリアルのための準備4 実践4.1 はじ ...

laravel logo

Laravel Sail 環境に Laravel Breeze を導入してみた

1 はじめに2 Laravel Sail とは3 Laravel Breeze とは4 Laravel Breeze のインストール4.1 Composer4.2 npm5 マイグレーション6 確認7 ...

フォロー

blog-page_side_responsive

2022年2月
 12345
6789101112
13141516171819
20212223242526
2728  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。