「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > ## Go で具象型を使用してインターフェイスのスライスを初期化するには?

## Go で具象型を使用してインターフェイスのスライスを初期化するには?

2024 年 11 月 10 日に公開
ブラウズ:619

## How to Initialize Slices of Interfaces with Concrete Types in Go?

Go でのインターフェイスと具象型によるジェネリック初期化

Go でジェネリック関数を作成する場合、具象型も受け入れると有益な場合があります。ただし、これらの特定の型の新しいインスタンスを使用してインターフェイスのスライスを初期化しようとすると、問題が発生します。

複数の型パラメーターを使用した初期試行

1 つのアプローチは論理的であるように思えるかもしれません。2 つの型パラメーターを定義することです。 1 つはスライス要素タイプ (X) 用で、もう 1 つはインスタンス化する具象タイプ (Y) 用です。ただし、このアプローチは、Y のインスタンスを X 型の要素に割り当てようとすると失敗します。

func Fill[X, Y any](slice []X){
   for i := range slice {
      slice[i] = new(Y) // not work!
   }
}

この問題は、コンパイラがインターフェイス X とその実装 Y の間の関係を失うために発生します。X と Y は両方とも別個の任意の型として扱われます。

明示的なキャストの使用

これに対処するには、関数内で明示的なキャスト操作を使用できます:

func Fill[X, Y any](slice []X) {
    for i := range slice {
        slice[i] = any(*new(Y)).(X)
    }
}

ただし、このアプローチでは、Y が X を実装していない場合にパニックが発生します。これは、*sync.Mutex (ポインター型) を sync.Locker.

に割り当てようとするようなシナリオで発生します。コンストラクター関数の利用

より堅牢でタイプセーフなソリューションには、コンストラクター関数の利用が含まれます:

func Fill[X any](slice []X, f func() X) {
    for i := range slice {
        slice[i] = f()
    }
}

この関数は、指定された型の新しいインスタンスを返すコンストラクター関数を受け入れます。これにより、具象型インスタンスを使用したスライスの簡潔かつ安全な初期化が可能になります。

Null 値の回避

具象型をポインター型でインスタンス化する場合は、次の点に注意することが重要です。 new(Y) は nil 値になります。これを回避するには、func() X { return &sync.Mutex{} }.

など、正しいポインター値を返すようにコンストラクター関数を調整できます。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3