Go での構造体のレンジング
Go では、構造体のスライスをレンジングする場合、範囲変数から取得した値がコピーされます。そのため、これらの値に加えられた変更は、元のスライスには影響しません。
次の例を考えてみましょう:
package main import ( "fmt" ) type myStruct struct { Name string Count int } func main() { chartRecords := []myStruct{} for i := 0; i < 5; i++ { n := myStruct{Count: i, Name: fmt.Sprintf("Joe%2d", i)} chartRecords = append(chartRecords, n) } fmt.Printf("======ORIGINAL VALUES========\n") for _, elem := range chartRecords { fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name) } fmt.Printf("======MODIFIED VALUES EXPECTED========\n") for _, elem := range chartRecords { elem.Count++ fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name) } fmt.Printf("======CHECK AGAIN AND VALUES ARE BACK TO ORIGINAL========\n") for _, elem := range chartRecords { fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name) } }
このコードを実行すると、次の出力が生成されます:
======ORIGINAL VALUES======== No: 0 | Count: 0 | Name = Joe 0 No: 1 | Count: 1 | Name = Joe 1 No: 2 | Count: 2 | Name = Joe 2 No: 3 | Count: 3 | Name = Joe 3 No: 4 | Count: 4 | Name = Joe 4 ======MODIFIED VALUES EXPECTED======== No: 1 | Count: 1 | Name = Joe 0 No: 2 | Count: 2 | Name = Joe 1 No: 3 | Count: 3 | Name = Joe 2 No: 4 | Count: 4 | Name = Joe 3 No: 5 | Count: 5 | Name = Joe 4 ======CHECK AGAIN AND VALUES ARE BACK TO ORIGINAL======== No: 0 | Count: 0 | Name = Joe 0 No: 1 | Count: 1 | Name = Joe 1 No: 2 | Count: 2 | Name = Joe 2 No: 3 | Count: 3 | Name = Joe 3 No: 4 | Count: 4 | Name = Joe 4
ご覧のとおり、範囲内の各要素の Count フィールドをインクリメントしたにもかかわらず、chartRecords スライスの値は変更されていません。これは、範囲変数 elem がスライス内の元の要素のコピーであるためです。
元のスライスを更新するには、更新された要素を対応するインデックスのスライスに割り当てる必要があります:
for i, elem := range chartRecords { elem.Count++ chartRecords[i] = elem }
この修正により、コードを再度実行すると、次の出力が生成されます。
======ORIGINAL VALUES======== No: 0 | Count: 0 | Name = Joe 0 No: 1 | Count: 1 | Name = Joe 1 No: 2 | Count: 2 | Name = Joe 2 No: 3 | Count: 3 | Name = Joe 3 No: 4 | Count: 4 | Name = Joe 4 ======MODIFIED VALUES EXPECTED======== No: 1 | Count: 1 | Name = Joe 0 No: 2 | Count: 2 | Name = Joe 1 No: 3 | Count: 3 | Name = Joe 2 No: 4 | Count: 4 | Name = Joe 3 No: 5 | Count: 5 | Name = Joe 4 ======CHECK AGAIN AND VALUES ARE STILL MODIFIED======== No: 1 | Count: 1 | Name = Joe 0 No: 2 | Count: 2 | Name = Joe 1 No: 3 | Count: 3 | Name = Joe 2 No: 4 | Count: 4 | Name = Joe 3 No: 5 | Count: 5 | Name = Joe 4
これで、chartRecords スライスの値が次のように更新されます。
以上がGo 範囲ループで構造体を変更しても元のスライスが更新されないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。