ホームページ > バックエンド開発 > Golang > インターフェイス実装へのポインターを受け入れる汎用 Go 関数を作成するにはどうすればよいですか?

インターフェイス実装へのポインターを受け入れる汎用 Go 関数を作成するにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2024-12-21 05:25:14
オリジナル
114 人が閲覧しました

How Can I Create a Generic Go Function That Accepts a Pointer to an Interface Implementation?

インターフェイス実装への汎用ポインター

Go では、インターフェイスへのポインターを受け入れる汎用関数を定義するのが難しい場合があります。 SomeMethod() を持つインターフェイス A を考えます:

type A interface {
  SomeMethod()
}
ログイン後にコピー

そして、構造体ポインターとして A の実装があると仮定します:

type Aimpl struct {}

func (a *Aimpl) SomeMethod() {}
ログイン後にコピー

関数を受け取るジェネリック関数 Handler を作成するにはA パラメータを使用する場合は、次のように定義することが望ましいでしょう。

func Handler[T A](callback func(result T)) {
  // Essentially what I'd like to do is result := &Aimpl{} (or whatever T is)
  callback(result)
}
ログイン後にコピー

ただし、これにはいくつかの制約があります。

任意の型パラメータを使用して試行します

最初は、ポインタ実装を許可するために型パラメータを使用してインターフェイスを定義できるように見えるかもしれません:

type MyA[T any] interface{
  A
  *T
}
ログイン後にコピー

ただし、次の場合は失敗します。 error:

result does not implement interface. It's a pointer to a type, not a type
ログイン後にコピー

解決策: Type Parameterized Interface

これを解決するには、実装型がポインターであることを必要とする型パラメーターを使用してインターフェイスを宣言できます。その型パラメータに:

type A[P any] interface {
    SomeMethod()
    *P
}
ログイン後にコピー

このインターフェイスを使用すると、Handler 関数は次のようになります。変更されました:

func Handler[P any, T A[P]](callback func(result T)) {
    result := new(P)
    callback(result)
}
ログイン後にコピー

これで、コードは期待どおりにハンドラーを呼び出すことができます:

Handler(func(a *Aimpl) { fmt.Printf("%#v\n", a) })
ログイン後にコピー

Interface Wrapper を使用した代替

の定義の場合は変更できません。別の方法としては、カスタムのインターフェース:

type MyA[P any] interface {
    A
    *P
}
ログイン後にコピー

それに応じてハンドラー関数を変更します:

func Handler[P any, T MyA[P]](callback func(result T)) {
    result := new(P)
    callback(result)
}
ログイン後にコピー

どちらのソリューションでも、インターフェース実装へのポインターを受け入れる汎用関数の作成が可能です。

以上がインターフェイス実装へのポインターを受け入れる汎用 Go 関数を作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート