ホームページ  >  記事  >  バックエンド開発  >  Go で外部パッケージから共通のメンバーを持つ構造体を処理するためのジェネリック関数を作成する方法

Go で外部パッケージから共通のメンバーを持つ構造体を処理するためのジェネリック関数を作成する方法

Linda Hamilton
Linda Hamiltonオリジナル
2024-10-27 09:49:30949ブラウズ

How to Write a Generic Function for Handling Structs with Common Members from an External Package in Go?

外部パッケージからの共通メンバーを持つ異なる構造体を処理するためのジェネリック関数

概要

共通メンバーを共有する複数の構造体を操作するジェネリック関数の作成特にこれらの構造体が外部パッケージに属している場合は、困難になる可能性があります。この記事では、このシナリオに対処するためのさまざまな解決策を検討します。

問題の定義

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 = &amp;messaging.AndroidConfig{...}
    ....
    return message
}</code>

ただし、このアプローチは、「message.Android 未定義 (type T にはフィールドまたはメソッド Android がありません)」というエラーが発生するため失敗します。

解決策1: 型スイッチ

簡単な解決策には、型スイッチを使用して特定の構造体の型を個別に処理することが含まれます。

<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: メソッドを使用したラッパー

共通メンバーへのアクセスが不可欠な場合、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>

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

多数の構造体がある状況では、リフレクションの方がより適切な解決策となる可能性があります。

<code class="go">func highPriority[T firebaseMessage](message T) T {
    cfg := &amp;messaging.Android{} 
    reflect.ValueOf(message).Elem().FieldByName("Android").Set(reflect.ValueOf(cfg))
    return message
}</code>

このアプローチではリフレクションを使用するため、フィールドがアドレス指定可能であることを確認することが不可欠であることに注意してください。

結論

特定の要件に応じて、適切なソリューションは大きく異なる可能性があります。 。この記事では、Go でそのようなシナリオを処理するためのいくつかの実行可能なオプションを提供します。

以上がGo で外部パッケージから共通のメンバーを持つ構造体を処理するためのジェネリック関数を作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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