ホームページ  >  記事  >  バックエンド開発  >  ジェネリックを使用して Go で共通のメンバーを持つ異なる構造体を操作するにはどうすればよいですか?

ジェネリックを使用して Go で共通のメンバーを持つ異なる構造体を操作するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-10-26 15:29:30693ブラウズ

How to Work with Different Structs with Common Members in Go Using Generics?

ジェネリックを使用した共通のメンバーを使用したさまざまな構造体の操作

Go では、上で動作するジェネリック関数を作成するシナリオに遭遇することがあります。共通のメンバーを共有するさまざまな構造体。ただし、共用体型制約を越えてこのような共通フィールドに直接アクセスすることは、Go 1.18 ではまだサポートされていません。

チャレンジ:

2 つのメッセージ構造体、Message と MulticastMessage を考えてみましょう。 Android など、同じタイプのフィールド。これらのフィールドを両方の構造体に追加する汎用関数を定義したいと考えています。ただし、両方の構造体を含むインターフェイスに制約された型パラメータを使用すると、それらの共通フィールドに直接アクセスできなくなります。

解決策:

解決策 1: 型Switch

関連する構造体が少数しかない場合は、型スイッチを使用できます。

<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>

解決策 2: メソッドを使用したラッパー

構造体の数が多い場合は、共通の機能を実装するメソッドで各構造体をラップすることを検討してください。

<code class="go">type wrappedMessage interface {
    *MessageWrapper | *MultiCastMessageWrapper
    SetConfig(c foo.Config)
}

func highPriority[T wrappedMessage](message T) T {
    message.SetConfig(messaging.Android{"some-value"})
    return message
}</code>

解決策 3: リフレクション

多くの構造体がある場合は、アドレス可能な構造体とフィールドが必要ですが、リフレクションの方が良い選択肢になる可能性があります:

<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>

メモと代替案:

  • 共通の場合メンバーはメソッドであるため、制約タイプごとにメソッドを明示的に実装する必要がある場合があります。
  • もう 1 つの方法は、共通メンバーにカスタム インターフェイスを使用することです。ただし、これには元の構造体を変更する必要があり、すべての場合に実行可能であるとは限りません。

以上がジェネリックを使用して Go で共通のメンバーを持つ異なる構造体を操作するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。