Golang では構造体のプロパティであるスライスに追加できないのはなぜですか?
Golang ではすべてが値によって渡されますつまり、オブジェクトが関数に引数として渡されるたびに、オブジェクトのコピーが作成されます。これにより、構造体のプロパティであるスライスに追加しようとすると、予期しない動作が発生する可能性があります。
問題: Test3
次の例を考えてみましょう:
package main import "fmt" type Test3 struct { all []int } func (c Test3) run() []int { c.combo() return c.all } func (c Test3) combo() { for i := 0; i < 2; i++ { c.all = append(c.all, i) fmt.Println("Test3 step", i+1, c.all) } } func main() { test3 := &Test3{} fmt.Println("Test3 final:", test3.run()) }
test3.run() を呼び出すと、test3 のコピーが作成され、実行に渡されます。次に run メソッドは combo を呼び出し、2 つの値を c.all に追加します。ただし、run が戻ると、test3 のコピーが破棄されるため、c.all への変更は失われます。これにより、出力に見られるように、空のスライスが返されます。
Test3 step 1 [0] Test3 step 2 [0 1] Test3 final: []
解決策: ポインター レシーバーの使用
この問題を解決するには、以下が必要です。コンボメソッドにポインタレシーバを使用します。これは、コピーの代わりに Test3 値へのポインターを渡すようにコンパイラーに指示します。
func (c *Test3) combo() { for i := 0; i < 2; i++ { c.all = append(c.all, i) fmt.Println("Test3 step", i+1, c.all) } }
ポインター レシーバーを使用すると、コンボ内の c.all に加えられた変更は、元の Test3 値に直接適用されます。参照によって渡されます。これにより、正しい出力が得られます。
Test3 step 1 [0] Test3 step 2 [0 1] Test3 final: [0 1]
値渡しの概念を理解し、ポインター レシーバーを適切に使用することで、Golang 構造体でスライスを操作するときに予期しない動作を回避できます。
以上がポインタ レシーバが使用されない限り、Golang 構造体メソッド内のスライスへの追加が機能しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。