ホームページ >バックエンド開発 >Golang >Go のポインター レシーバーでメソッド呼び出しのチェーンが失敗するのはなぜですか?

Go のポインター レシーバーでメソッド呼び出しのチェーンが失敗するのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-29 13:03:10577ブラウズ

Why Does Chaining Method Calls Fail with Pointer Receivers in Go?

Go の「アドレスを取得できません」と「ポインタ メソッドを呼び出すことができません」を理解する

同様の機能にもかかわらずコード スニペットのうち、1 つはコンパイルして動作しますが、もう 1 つはエラーを生成します:

// This compiles and works
diff := projected.Minus(c.Origin)
dir := diff.Normalize()

// This does not (yields the errors in the title)
dir := projected.Minus(c.Origin).Normalize()

不均衡は、Normalize() メソッドのレシーバー タイプの違いに起因します。

Go メソッドのレシーバー タイプ

Go メソッドは、値レシーバーまたはポインターのいずれかを使用できます。受信機。値レシーバーは構造体のコピーを操作し、ポインター レシーバーは元の構造体自体を操作します。

Normalize() の場合、ポインター レシーバーがあり、Vector3 値へのポインターが必要です。レシーバー。

変数と戻り値のアドレス指定

変数Go ではアドレス指定可能です。つまり、変数のアドレスを引数としてポインター レシーバー メソッドに渡すことができます。ただし、関数およびメソッド呼び出しの戻り値はアドレス指定できません。

ポインター レシーバーによる呼び出しの連鎖

コンパイルする例では、コンパイラーは自動的にアドレスを取得します。 Normalize() のポインタ レシーバと一致するように diff 変数を設定します。

コンパイルしない例では、コンパイラはMinus() の戻り値のアドレスはアドレス指定できないため、自動的に取得できません。戻り値はコピーであるため、そのアドレスを取得できるように、最初に変数に割り当てる必要があります。

回避策

問題を解決するには、いくつかの回避策が存在します。 :

  • 値レシーバー: Normalize() を次のように変更します値レシーバーがあり、戻り値のアドレスを取得する必要がなくなります。
  • ポインター戻り値: Vector3 へのポインターを返すように Minus() を変更します。
  • ヘルパー関数: 値のアドレスを返すヘルパー関数を作成し、必要な連鎖を可能にします。

レシーバーと結果の型の一貫性

カスタム タイプ全体でレシーバーと結果の型の一貫性を維持することをお勧めします。ほとんどのメソッドにポインター レシーバーがある場合、すべてのメソッドでポインター レシーバーを使用する必要があります。同様に、ほとんどのメソッドがポインタを返す場合、すべてのメソッドがポインタを返す必要があります。

以上がGo のポインター レシーバーでメソッド呼び出しのチェーンが失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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