go开发遇到的坑--range

本文通过一个Go语言实例,展示了如何正确使用切片与映射,并避免常见的编程陷阱。文章解释了为何直接将切片元素的地址存入映射可能导致所有键都指向最后一个元素的问题,并给出了两种解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看下下面的代码

package main

import "fmt"
type coder struct {
    Name string
    Age  int
}


func main() {
    m := make(map[string]*coder)
    coders := []coder{
        {Name: "han", Age: 24},
        {Name: "li", Age: 24},
        {Name: "song", Age: 25},
    }
    for _, co := range coders {
        m[co.Name] = &coder
        fmt.Printf("%p\n",&co)
    }
    for k,v:=range m{
        fmt.Printf("%v--->%v\n",k,v)
    }

}

运行的结果如下:

0xc42000a1a0
0xc42000a1a0
0xc42000a1a0
song--->&{song 25}
han--->&{song 25}
li--->&{song 25}

我们发现结果m的值只会指向一个值。这样的写法初学者经常会遇到的,很危险! 与Java的foreach一样,都是使用副本的方式。所以m[co.Name]=&stu实际上一致指向同一个指针, 最终该指针的值为遍历的最后一个struct的值拷贝。 就像想修改切片元素的属性:

for _, co:= range coders {
    co.Age = co.Age+10
}

这样也是错误的。其正确的做法应该如下:
1.利用for循环,带下标的那种:

for _,co :=range coders{
        stu.Age=stu.Age+10
        fmt.Println(stus)
    }

2.直接用指针数组

m := make(map[string]*coder)
    stus := []*coder{
        {Name: "han", Age: 24},
        {Name: "li", Age: 24},
        {Name: "song", Age: 25},
    }
    for _, co := range coders {
        m[stu.Name] = stu
        fmt.Printf("%p\n",&stu)
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值