外部パッケージを使用する場合、共通のメンバーを含む構造体で動作するジェネリック関数を定義するのが難しい場合があります。この記事では、2 つの異なる Firebase メッセージ構造体 Message と MulticastMessage の共有フィールドを変更する汎用関数を作成しようとした問題について説明します。
Android 構成フィールドと同様に、これらの構造体には明示的な関係がなく、型パラメーターを使用して共通プロパティに直接アクセスしようとするとエラーが発生します。この理由は、リンクされたスレッドで説明されているように、Go 1.18 は型パラメータの共通フィールドまたはメソッドへのアクセスをまだサポートしていないためです。
この問題に対処するには、いくつかの解決策があります。提案:
関係する型の数が制限されている場合は、型スイッチ ステートメントを使用して共有フィールドにアクセスできます:
<code class="go">func highPriority[T firebaseMessage](message T) T { switch m := any(message).(type) { case *messaging.Message: setConfig(m.Android) case *messaging.MulticastMessage: setConfig(m.Android) } return message }</code>
このメソッドには、ジェネリック関数で使用する追加メソッドを含むラッパー構造体の作成が含まれます:
<code class="go">type MessageWrapper struct { messaging.Message } func (w *MessageWrapper) SetConfig(cfg messaging.Android) { *w.Android = cfg }</code>
ジェネリック関数は、この共通メソッドにアクセスできます:
<code class="go">func highPriority[T wrappedMessage](message T) T { message.SetConfig(messaging.Android{"some-value"}) return message }</code>
構造体の数が多い場合、リフレクションを使用して共有フィールドに動的にアクセスできます。
<code class="go">func highPriority[T firebaseMessage](message T) T { cfg := &messaging.Android{} reflect.ValueOf(message).Elem().FieldByName("Android").Set(reflect.ValueOf(cfg)) return message }</code>
これらのソリューションには次のような特徴があることに注意することが重要です。その制限:
以上がGo でジェネリックを使用して異なる構造体の共有フィールドを処理するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。