Go でメソッドを記述する場合、重要な決定の 1 つは、構造体を値で渡すかポインターで渡すかです。この選択は、パフォーマンス、コードの動作、メモリ割り当てに影響を与える可能性があります。この投稿では、実際の例を使用してこの違いを検討し、それぞれのアプローチがどのような場合に適切であるかを理解します。
小さな構造体と 2 つのメソッドから始めましょう。1 つは構造体が値によって渡され、もう 1 つはポインタによって渡されます。
package main import ( "fmt" ) type Person struct { Name string Age int } // Method with struct passed by value func (p Person) CelebrateBirthdayValue() { p.Age++ } // Method with struct passed by pointer func (p *Person) CelebrateBirthdayPointer() { p.Age++ } func main() { person := Person{Name: "Alice", Age: 30} // Passing by value person.CelebrateBirthdayValue() fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30 // Passing by pointer person.CelebrateBirthdayPointer() fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31 }
構造体をメソッドに値で渡すと、Go は構造体のコピーを作成します。独立したコピーを使用しているため、メソッド内の構造体に加えられた変更は元の構造体には影響しません。
一方、構造体をポインタで渡す場合は、元の構造体のメモリ アドレスを渡します。これは、同じインスタンスを操作しているため、メソッド内の構造体に加えられた変更は、元の構造体を直接変更することを意味します。
要約:
値による: メソッドは構造体のコピーを受け取り、新しいメモリ空間を作成します。
ポインタによる: メソッドは、同じメモリ空間を指す、元の構造体のメモリ アドレスを受け取ります。
構造体が値によって渡されると、コピーがスタックに割り当てられます。これは一般に高速で効率的です。ただし、構造体が大きい場合、コピーによって大量のスタック メモリが消費される可能性があります。
構造体がポインターによって渡される場合、ポインター自体はスタック上に割り当てられますが、特に new、make を使用して作成された場合、または匿名関数によってキャプチャされた場合には、元の構造体がヒープ上に割り当てられる可能性があります。
ヒープ割り当ては、割り当て時間とガベージ コレクションの点でより高価ですが、構造体全体をコピーせずに大量のデータを効率的に操作できます。
構造体を値で渡すことは、次の場合に役立ちます。
例:
func (p Person) GetName() string { return p.Name }
ここで、GetName は Name フィールドのみを読み取り、構造体の状態を変更せずに文字列を返します。
ポインターによる構造体受け渡しは、次の場合に有益です。
例:
package main import ( "fmt" ) type Person struct { Name string Age int } // Method with struct passed by value func (p Person) CelebrateBirthdayValue() { p.Age++ } // Method with struct passed by pointer func (p *Person) CelebrateBirthdayPointer() { p.Age++ } func main() { person := Person{Name: "Alice", Age: 30} // Passing by value person.CelebrateBirthdayValue() fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30 // Passing by pointer person.CelebrateBirthdayPointer() fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31 }
この場合、UpdateName は元の構造体の Name フィールドを直接変更します。これは、コピーを作成するよりも効率的です。
Go でメソッドを作成するときに、構造体を値で渡すかポインターで渡すかを決定することは、パフォーマンス、コードの動作、メモリ割り当てに影響を与える可能性がある重要な選択です。
値による受け渡しは、メソッド内で構造体の不変性を確保するのに役立ちますが、ポインターによる受け渡しは、元の構造体を変更して、より大きな構造体を操作する場合のパフォーマンスを最適化するために不可欠です。
以上がポインタとメソッドの値の違いの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。