1、忽视在range循环中元素被复制的事实
修改结构体切片中的元素
错误的修改方式(要注意:在range循环中,值元素是一个拷贝!)
package tests import ( "fmt" "testing" ) type Account struct { Balance int } func TestT1(t *testing.T) { accounts := []Account{ {Balance: 10}, {Balance: 20}, {Balance: 30}, } // 1、这样做不会修改 for _, a := range accounts { // 只改变了临时变量a,并没有改变切片中的元素 a.Balance += 100 } fmt.Println("accounts: ", accounts) // accounts: [{10} {20} {30}] }
正确的修改方式1:使用切片的索引访问元素
package tests import ( "fmt" "testing" ) type Account struct { Balance int } func TestT1(t *testing.T) { accounts := []Account{ {Balance: 10}, {Balance: 20}, {Balance: 30}, } for idx, _ := range accounts { accounts[idx].Balance += 100 } fmt.Println("accounts: ", accounts) // accounts: [{110} {120} {130}] }
正确的修改方式2:传统的for循环实现,实际上也是通过索引的方式修改
package tests import ( "fmt" "testing" ) type Account struct { Balance int } func TestT1(t *testing.T) { accounts := []Account{ {Balance: 10}, {Balance: 20}, {Balance: 30}, } for i := 0; i < len(accounts); i++ { accounts[i].Balance += 100 } fmt.Println("accounts: ", accounts) // accounts: [{110} {120} {130}] }
正确的修改方式4:改成访问“切片结构体指针”
但是书中又提到了:“如果性能很重要,由于缺乏可预测性,CPU在指针上的迭代效率可能比较低(书中错误#91中会有讨论)”
package tests import ( "fmt" "testing" ) type Account struct { Balance int } func TestT1(t *testing.T) { accounts := []*Account{ {Balance: 10}, {Balance: 20}, {Balance: 30}, } for _, val := range accounts { val.Balance += 200 } for _, val := range accounts { fmt.Println("val.Balance: ", val.Balance) } /* val.Balance: 210 val.Balance: 220 val.Balance: 230 */ }
23
123
123
123
123
参考
注意一下,个人建议还是买纸质版的书,下面的博客里面因为是机翻的,所以不可避免会有一些看起来很难理解的地方~
https://gomis100.flygon.net/#/docs/03
标签:Account,val,fmt,testing,控制结构,accounts,Go,新手,Balance From: https://www.cnblogs.com/paulwhw/p/18287691