开门见山,在golang中,for range
中,接收到的item
用的是同一个地址,因为for range创建了每个元素的副本,而不是直接返回每个元素的引用,也就是说,以下代码将会不符合预期:
package main
import "fmt"
type A struct {
AA string `json:"aa"`
}
type B struct {
AA *string `json:"aa"`
}
func main() {
arr := []A{{"1"}, {"2"}, {"3"}, {"4"}, {"5"}}
res := make([]*B, 0)
for i, item := range arr {
fmt.Printf("item: %p, AA:%p, index:%v\n", &item, &item.AA, i)
res = append(res, &B{AA: &item.AA})
}
for _, b := range res {
fmt.Printf("%v ", *b.AA)
}
}
输出:
item: 0xc000116210, AA:0xc000116210, index:0
item: 0xc000116210, AA:0xc000116210, index:1
item: 0xc000116210, AA:0xc000116210, index:2
item: 0xc000116210, AA:0xc000116210, index:3
item: 0xc000116210, AA:0xc000116210, index:4
5 5 5 5 5
是的没错,最终res的值是555,这里有点反常识
因为for range
每次遍历的时候,都拷贝了一份到item
里面,并且item的指针永远指向同一个,因此,最终他们的值都是5
如何解决?很简单,直接访问slice中的元素而非访问拷贝的元素即可:
func main() {
arr := []A{{"1"}, {"2"}, {"3"}, {"4"}, {"5"}}
res := make([]*B, 0)
//for i, item := range arr {
// fmt.Printf("item: %p, AA:%p, index:%v\n", &item, &item.AA, i)
// res = append(res, &B{AA: &item.AA})
//}
for i, _ := range arr {
res = append(res, &B{AA: &arr[i].AA})
}
for _, b := range res {
fmt.Printf("%v ", *b.AA)
}
}
输出:
1 2 3 4 5
9 条评论
你的文章内容非常用心,让人感动。 http://www.55baobei.com/k67Lj6n1ka.html
真好呢
《我们第一季(豪华版)》欧美剧高清在线免费观看:https://www.jgz518.com/xingkong/146015.html
《狐狸女士第一季(重制版)》欧美剧高清在线免费观看:https://www.jgz518.com/xingkong/137975.html
176每日新开传奇私服网如何吸引玩家注册?:https://501h.com/jingpin/2024-08-21/29540.html
想想你的文章写的特别好www.jiwenlaw.com
想想你的文章写的特别好https://www.jiwenlaw.com/
不错不错,我喜欢看
叼茂SEO.bfbikes.com