Core Types

この型セットベースのアプローチは非常に柔軟で、元のジェネリクス提案の意図に沿っています。ジェネリック型の操作数を含む操作は、各型制約によって許可されるすべての型に対して有効であれば、有効であるべきです。実装に関して事態を簡素化するため、後でルールを緩和できることを知った上で、このアプローチは普遍的には選択_されませんでした_。代わりに、たとえばSend文に対して、仕様では以下のように述べています:

チャンネル式の_core type_はチャンネルでなければならず、チャンネルの向きはsend操作を許可しなければならず、送信される値の型はチャンネルの要素型に代入可能でなければならない。

これらのルールはcore typeの概念に基づいており、大まかに以下のように定義されます:

  • 型が型パラメータでない場合、そのcore typeは単にその基底型です。
  • 型が型パラメータである場合、core typeは型パラメータの型セット内のすべての型の単一の基底型です。型セットが_異なる_基底型を持つ場合、core typeは存在しません。

たとえば、interface{ ~[]int }はcore type([]int)を持ちますが、上記のConstraintインターフェースはcore typeを持ちません。さらに複雑なことに、チャンネル操作や特定の組み込み呼び出し(appendcopy)に関しては、上記のcore typeの定義は制限的すぎます。実際のルールには、異なるチャンネル方向と[]bytestring型の両方を含む型セットを許可する調整があります。

このアプローチには様々な問題があります:

  • core typeの定義は異なる言語機能に対して健全な型ルールを導く必要があるため、特定の操作に対して過度に制限的です。たとえば、Go 1.24のスライス式のルールはcore typeに依存しており、その結果、Constraintによって制約された型Sの操作数をスライスすることは、有効である可能性があるにもかかわらず許可されません。

  • 特定の言語機能を理解しようとするとき、非ジェネリックコードを考慮していても、core typeの複雑さを学ぶ必要があるかもしれません。スライス式について再び考えると、言語仕様ではスライスされる操作数のcore typeについて語っており、操作数は配列、スライス、または文字列でなければならないと直接述べるのではありません。後者の方がより直接的で、シンプルで、明確であり、具体的なケースでは無関係かもしれない別の概念を知る必要がありません。

  • core typeの概念が存在するため、インデックス式、lencap(およびその他)のルールは、すべてcore typeを回避し、言語における例外として現れるのではなく、規範として現れます。逆に、core typeはissue #48522のような提案を引き起こします。これは、セレクターx.fxの型セットのすべての要素によって共有されるフィールドfにアクセスすることを許可するもので、言語により多くの例外を追加するように見えます。core typeがなければ、その機能は非ジェネリックフィールドアクセスの通常のルールの自然で有用な結果となります。