go程序开发者们很容易犯的for循环陷阱

简介: go程序使用for循环需要注意的一点,不然会踩坑的

看如下的go程序demo

循环读取一个slice,把读取的值放入另一个slice

packagemainimport"fmt"typeFoostruct {
barstring}
funcmain() {
list := []Foo{
        {"A"},
        {"B"},
        {"C"},
    }
list2 :=make([]*Foo, len(list))
fori, value :=rangelist {
//fmt.Printf("%p\n",&value)list2[i] =&value    }
fmt.Println(list[0], list[1], list[2])
fmt.Println(list2[0], list2[1], list2[2])
}


理想中的预期运行结果应该是

{A} {B} {C}
&{A} &{B} &{C}


但是当你实际运行后,结果不是这样了

{A} {B} {C}
&{C} &{C} &{C}


为什么是这样的结果呢?

首先我们应该知道, for 循环中,初始变量会被重用,例如: ivalue ,在 for 之前被分配内存地址,之后循环只是一直对这个内存地址重新赋值,我们可以把代码注释去掉看看执行结果

0xc0001041e0
0xc0001041e0
0xc0001041e0
{A} {B} {C}
&{C} &{C} &{C}

从执行结果中,可以看到内存地址一样,而在for循环最后元素时, value的值是 C,而 &value是一个指向 value的内存地址,如果想得到预期的结果该怎么做

packagemainimport"fmt"typeFoostruct {
barstring}
funcmain() {
list := []Foo{
        {"A"},
        {"B"},
        {"C"},
    }
list2 :=make([]*Foo, len(list))
fori, value :=rangelist {
//每次循环都重新声明一个变量temp:=valuefmt.Printf("%p\n",&temp)
list2[i] =&temp    }
fmt.Println(list[0], list[1], list[2])
fmt.Println(list2[0], list2[1], list2[2])
}


运行结果

0xc0001041e0
0xc0001041f0
0xc000104200
{A} {B} {C}
&{A} &{B} &{C}


希望开发者写代码过程中,注意这个坑,不然很容易犯这个错误

目录
相关文章
|
1月前
|
Go
go语言中在 for 循环中使用 break
go语言中在 for 循环中使用 break
30 4
|
1月前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
28 2
|
20天前
|
Go
go语言使用传统的for循环
go语言使用传统的for循环
23 7
|
20天前
|
存储 Go 索引
go语言使用for循环遍历
go语言使用for循环遍历
28 7
|
1月前
|
Go
go语言中控制循环
go语言中控制循环
36 14
|
1月前
|
Go 索引
go语音中range 循环
go语音中range 循环
41 12
|
24天前
|
测试技术 Go 索引
go语言通过 for 循环遍历
go语言通过 for 循环遍历
27 3
|
1月前
|
Go
go语言中无限循环
go语言中无限循环
29 9
|
1月前
|
Java Go
go语言中for循环
go语言中for循环
29 3
Go语言的条件控制语句及循环语句的学习笔记
本文是Go语言的条件控制语句和循环语句的学习笔记,涵盖了if语句、if-else语句、if嵌套语句、switch语句、select语句以及for循环和相关循环控制语句的使用方法。
Go语言的条件控制语句及循环语句的学习笔记