オブジェクトを使用したポインターを対象としたメソッドの呼び出し
Go では、それへのポインタの代わりにオブジェクトを使用します。これは珍しいように思えるかもしれませんが、Go 仕様に従って許可されています。
次のコードを考えてみましょう:
package main import "math" type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func (v *Vertex) Scale(f float64) { v.X = v.X * f v.Y = v.Y * f } func main() { v := Vertex{3, 4} v.Scale(10) // v is not a pointer to a Vertex object fmt.Println(v.Abs()) }
この例では、v は Vertex 型のオブジェクトで、Scale はVertex へのポインターを対象としたメソッド。ただし、v へのポインターを渡す代わりに、v.Scale(10) を直接呼び出します。
これがエラーではないのはなぜですか?答えは、Go 仕様で定義されているメソッド呼び出しのルールにあります。
If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().
このルールは、呼び出される値がアドレス指定可能 (つまり、ローカル変数またはポインタである) の場合、呼び出しを行うことを示しています。そのメソッドは、そのアドレスでメソッドを呼び出すことと同じです。この場合、v はローカル変数であるため、v.Scale(10) は、代わりに (&v).Scale(10) を記述したかのように解釈されます。
この利便性により、よりクリーンで簡潔な記述が可能になります。メソッドを呼び出す前にオブジェクトへのポインタを明示的に作成する必要がなく、コードを作成できます。ただし、これはポインタ レシーバを備えたメソッドに対してのみ機能することに注意することが重要です。値レシーバーを持つメソッドの場合、オブジェクトへのポインターを渡すことは許可されません。
以上がポインターの代わりにオブジェクトを使用して、ポインター レシーバーで Go メソッドを呼び出すことができるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。