ホームページ  >  記事  >  バックエンド開発  >  ジェネリック関数はパッケージ間で関連のない構造体の共有フィールドを変更できますか?

ジェネリック関数はパッケージ間で関連のない構造体の共有フィールドを変更できますか?

DDD
DDDオリジナル
2024-10-27 10:20:03920ブラウズ

 Can Generic Functions Modify Shared Fields in Unrelated Structs Across Packages?

ジェネリック関数は外部パッケージ構造体全体の共有メンバーと連携できますか?

問題:

目標は、さまざまな Firebase メッセージ構造体全体で特定のフィールドを変更できる汎用関数。同様のタイプの重複フィールドがあるにもかかわらず、Message 構造体と MulticastMessage 構造体には明示的な関係がありません。ただし、インターフェイス制約を使用してこれを処理しようとすると、エラーが発生します。

解決策 1: 型の切り替え

共用体の型の数が少ない場合、タイプスイッチアプローチは機能する可能性があります。これには、各タイプを手動で処理し、適切なメソッドを呼び出して目的のフィールド値を設定することが含まれます。

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
}

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

別の解決策には、ラッピングが含まれます。元の構造体と、共有フィールドの設定に使用できるラッパー内の共通メソッドの定義。

type wrappedMessage interface {
    *MessageWrapper | *MultiCastMessageWrapper
    SetConfig(c foo.Config)
}

type MessageWrapper struct {
    messaging.Message
}

func (w *MessageWrapper) SetConfig(cfg messaging.Android) {
    *w.Android = cfg
}

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

より大きな構造体を処理する場合構造体の数に応じて、リフレクションを使用して共有フィールドを動的に設定できます。ただし、これには構造体とフィールドがアドレス可能である必要があることに注意してください。

func highPriority[T firebaseMessage](message T) T {
    cfg := &messaging.Android{} 
    reflect.ValueOf(message).Elem().FieldByName("Android").Set(reflect.ValueOf(cfg))
    return message
}

注:

  • 解決策 2 は最も柔軟性が高く、型を許可します。
  • 解決策 3 はより一般的なアプローチですが、リフレクションが必要であり、パフォーマンスのオーバーヘッドが発生する可能性があります。

以上がジェネリック関数はパッケージ間で関連のない構造体の共有フィールドを変更できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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