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}


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

目录
相关文章
|
6月前
|
Go
Go 1.22 for 循环的两处重要更新
本文介绍了 Go 1.22 版本对 for 循环所做的两处重要更新:循环的每次迭代都会创建新变量 和 循环支持对整数范围进行迭代。 - 循环的每次迭代都会创建新变量,有效避免了以往版本中常见的闭包陷阱,提高了代码的安全性和可预测性。 - 循环支持对整数范围进行迭代,极大地增强了 for 循环的灵活性,使得编写计数循环更加直接和简洁。
104 1
Go 1.22 for 循环的两处重要更新
|
6月前
|
JSON JavaScript Go
Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
掌握 Go 语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解 Go 基础知识的好起点是查阅 Go 官方文档
936 2
|
4天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
13 2
Go语言的条件控制语句及循环语句的学习笔记
本文是Go语言的条件控制语句和循环语句的学习笔记,涵盖了if语句、if-else语句、if嵌套语句、switch语句、select语句以及for循环和相关循环控制语句的使用方法。
Go语言的条件控制语句及循环语句的学习笔记
|
1月前
|
Go 索引
go基础-6.for循环
go基础-6.for循环
|
3月前
|
存储 编译器 Go
|
3月前
|
Go
Go1.22 新特性:for 循环不再共享循环变量,且支持整数范围
Go1.22 新特性:for 循环不再共享循环变量,且支持整数范围
|
6月前
|
Go
Go 语言循环语句
Go 语言循环语句
33 0
|
5月前
|
Go
go循环语句
go循环语句
|
6月前
|
Go 开发者
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
【4月更文挑战第21天】本文介绍了Go语言中的流程控制语句,包括`if`、`switch`和`for`循环。`if`语句支持简洁的语法和初始化语句,但需注意比较运算符的使用。`switch`语句提供多分支匹配,可省略`break`,同时支持不带表达式的形式。`for`循环有多种形式,如基本循环和`for-range`遍历,遍历时修改原集合可能导致未定义行为。理解并避免易错点能提高代码质量和稳定性。通过实践代码示例,可以更好地掌握Go语言的流程控制。
52 3
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解