golang rang指针数据的坑

文章讲述了在Golang中使用for循环时,由于tmp变量在循环中的值被改变,导致输出不按序的问题,以及如何通过值传递参数解决这一问题。

仅为记录学习golang过程中遇到的坑

func main()  {
	type data struct {
		num int
	}

	datas := []data{
		{1},
		{2},
		{3},
		{4},
		{5},
	}

	for _,tmp := range datas{
		go func(d *data) {
			fmt.Println(d.num)
		}(&tmp)
	}

	time.Sleep(10 * time.Second)
}

预期输出:
1,2,3,4,5 (不会按序输出,但是每个数字有且只有一次)
实际输出:
4,5,5,5,5

这是由于tmp只声明了一次,在for循环过程中被改变了值,指向的数据发生了变化,所以在对tmp取内存地址时,会导致数据变化。

可以采用如下方式修改,或者采用值传递参数

func main()  {
	type data struct {
		num int
	}

	datas := []data{
		{1},
		{2},
		{3},
		{4},
		{5},
	}

	for index,_ := range datas{
		go func(d *data) {
			fmt.Println(d.num)
		}(&datas[index])
	}

	time.Sleep(10 * time.Second)
}

推荐阅读

1、原来阿里字节员工简历长这样
2、一条SQL差点引发离职
3、MySQL并发插入导致死锁


如果你也觉得我的分享有价值,记得点赞或者收藏哦!你的鼓励与支持,会让我更有动力写出更好的文章哦!

### Golang 中通过指针访问结构体成员变量的方法 在 Go 语言中,可以通过结构体指针来访问其成员变量。当使用指针访问结构体成员时,不需要显式解引用操作符 `*`,可以直接通过点号 `. ` 访问成员变量[^1]。 以下是具体说明以及代码示例: #### 结构体指针的定义与初始化 创建一个指向结构体的指针有两种常见方式: 1. 使用取地址运算符 `&` 获取结构体实例的地址。 2. 使用内置函数 `new()` 来分配内存并返回该结构体类型的指针。 ```go package main import "fmt" type Hero struct { Name string Skins []string } func main() { // 方式一:通过已有的结构体实例获取指针 hero := Hero{Name: "XiaoQiao"} fa := &hero (*fa).Skins = append((*fa).Skins, "青蛇") // 显式解引用 fmt.Println(hero) // 方式二:使用 new 函数直接创建结构体指针 fb := new(Hero) fb.Name = "DianWei" fb.Skins = append(fb.Skins, "赤焰枪神") fmt.Println(*fb) } ``` 上述代码展示了两种不同的方法来初始化结构体指针,并通过它们访问和修改成员变量[^4]。 #### 隐式解引用机制 Go 提供了一种便利特性——隐式解引用。这意味着如果已经拥有一个结构体指针,则无需手动执行解引用即可直接访问其中的字段或调用方法。例如,在上面的例子中,也可以这样写: ```go fa.Skins = append(fa.Skins, "白蛇") // 自动处理解引用 ``` 这种简化语法不仅提高了可读性,还减少了潜在错误的发生概率[^5]。 #### 匿名字段的支持 除了常规命名字段外,Go 还支持匿名字段的概念。对于包含匿名字段的复杂嵌套结构来说,即使这些字段本身也是由其他结构组成的情况下,仍然能够方便快捷地利用指针对目标数据进行定位与操控[^2]。 假设存在如下定义: ```go type Address struct { City string Province string } type User struct { ID int Username string Address // 匿名字段 } ``` 那么就可以像下面这样做: ```go u := &User{ ID: 1, Username: "Alice", Address: Address{"Beijing", "BJ"}, } // 修改匿名字段中的属性 u.City = "Shanghai" fmt.Printf("%+v\n", u) ``` 这里需要注意的是,尽管表面上看起来像是直接作用于顶层对象上一样简单明了的操作实际上背后涉及到了多层间接寻址过程。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值