共通メンバーを共有する複数の構造体を操作するジェネリック関数の作成特にこれらの構造体が外部パッケージに属している場合は、困難になる可能性があります。この記事では、このシナリオに対処するためのさまざまな解決策を検討します。
Message や MulticastMessage などの Firebase メッセージ構造体に特定のフィールドを追加する関数を記述する要件を考えてみましょう。どちらの構造体にも同じタイプの Android フィールドと APNS フィールドが含まれていますが、相互の関係を明示的に宣言していません。
最初に、汎用インターフェイス firebaseMessage を定義しようとする可能性があります。を作成し、次のように関数を実装します。
<code class="go">type firebaseMessage interface { *messaging.Message | *messaging.MulticastMessage } func highPriority[T firebaseMessage](message T) T { message.Android = &messaging.AndroidConfig{...} .... return message }</code>
ただし、このアプローチは、「message.Android 未定義 (type T にはフィールドまたはメソッド Android がありません)」というエラーが発生するため失敗します。
簡単な解決策には、型スイッチを使用して特定の構造体の型を個別に処理することが含まれます。
<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>
これは、共用体の型の数が制限されている場合に効果的に機能します。
共通メンバーへのアクセスが不可欠な場合、1 つのアプローチは、共用体内のすべての構造体から呼び出すことができる共通メソッドを使用してラッパー構造体を作成することです。欠点は、異なる型に対して複数のラッパー構造体を作成する必要があることです。
<code class="go">type wrappedMessage interface { *MessageWrapper | *MultiCastMessageWrapper SetConfig(c foo.Config) } type MessageWrapper struct { messaging.Message } func (w *MessageWrapper) SetConfig(cfg messaging.Android) { *w.Android = cfg } // same for MulticastMessageWrapper</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 でそのようなシナリオを処理するためのいくつかの実行可能なオプションを提供します。
以上がGo で外部パッケージから共通のメンバーを持つ構造体を処理するためのジェネリック関数を作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。