如何在go中使用带有for循环的列表

Posted

技术标签:

【中文标题】如何在go中使用带有for循环的列表【英文标题】:How to use list with for loops in go 【发布时间】:2020-02-13 05:04:14 【问题描述】:

我想将数字附加到列表中,但我的切片仅在 for 循环中更新值。

如何在外面更新?

slice := []int5,4,3,2,1

for i := 0; i < len(slice); i++ 
    slice := append(slice, i)
    fmt.Println(slice)


fmt.Println(slice)

实际结果

[5 4 3 2 1 0]
[5 4 3 2 1 1]
[5 4 3 2 1 2]
[5 4 3 2 1 3]
[5 4 3 2 1 4]
[5 4 3 2 1]

预期结果

[5 4 3 2 1 0]
[5 4 3 2 1 1]
[5 4 3 2 1 2]
[5 4 3 2 1 3]
[5 4 3 2 1 4]
[5 4 3 2 1 0 1 2 3 4]

这段代码在 Python 中工作,但在 go 中有一些我没有捕捉到的东西

【问题讨论】:

循环内的sliceblock作用域 【参考方案1】:

您不会将append() 的结果存储在“原始”slice 中,因为您使用short variable declaration 而不是assignment:

slice := append(slice, i)

短变量声明(因为它与原始 slice 变量位于不同的块中)创建一个新变量(遮蔽外部 slice),并在循环内打印这个新变量多变的。所以每次追加的结果只在循环体内可见,并在迭代结束时丢失。而是使用赋值:

slice = append(slice, i)

但是,当你这样做时,你会得到一个无限循环,因为你的循环条件是i &lt; len(slice),而slice 在每次迭代中都会增长。

相反,您应该这样做(评估len(slice) 一次并存储它):

for i, length := 0, len(slice); i < length; i++ 
    slice = append(slice, i)
    fmt.Println(slice)

输出将是(在Go Playground 上尝试):

[5 4 3 2 1 0]
[5 4 3 2 1 0 1]
[5 4 3 2 1 0 1 2]
[5 4 3 2 1 0 1 2 3]
[5 4 3 2 1 0 1 2 3 4]
[5 4 3 2 1 0 1 2 3 4]

请注意,如果您使用 for range,您会得到相同的结果,因为它只计算切片一次:

for i := range slice 
    slice = append(slice, i)
    fmt.Println(slice)

在Go Playground 上试试这个。

【讨论】:

以上是关于如何在go中使用带有for循环的列表的主要内容,如果未能解决你的问题,请参考以下文章

带有指针值的 Go 通道在 for 循环中的行为不符合预期[重复]

Go 语言设计:for 和 range 是如何实现的

如何在带有 for 循环的 bash 脚本中使用标志?

列表如何在 python 中使用 for 循环实际工作?

Go+ 列表解析 list comprehension

Go+ 列表解析 list comprehension