提问人:tatsuhirosatou 提问时间:10/16/2011 最后编辑:Tiago Peczenyjtatsuhirosatou 更新时间:11/10/2022 访问量:585804
Go 中有 foreach 循环吗?
Is there a foreach loop in Go?
答:
带有“range”子句的“for”语句遍历所有条目 数组、切片、字符串或映射,或通道上接收的值。 对于每个条目,它将迭代值分配给相应的迭代 变量,然后执行该块。
举个例子:
for index, element := range someSlice {
// index is the index where we are
// element is the element from someSlice for where we are
}
如果你不关心索引,你可以使用:_
for _, element := range someSlice {
// element is the element from someSlice for where we are
}
下划线 是空白标识符,是一个匿名占位符。_
评论
element
element
_()
_
_
_
for
_
_
下面的示例演示如何在循环中使用运算符来实现循环。range
for
foreach
func PrintXml (out io.Writer, value interface{}) error {
var data []byte
var err error
for _, action := range []func() {
func () { data, err = xml.MarshalIndent(value, "", " ") },
func () { _, err = out.Write([]byte(xml.Header)) },
func () { _, err = out.Write(data) },
func () { _, err = out.Write([]byte("\n")) }} {
action();
if err != nil {
return err
}
}
return nil;
}
该示例循环访问函数数组,以统一函数的错误处理。一个完整的例子是在谷歌的游乐场。
PS:它还表明,悬挂大括号对于代码的可读性来说是一个坏主意。提示:条件在通话前结束。很明显,不是吗?for
action()
评论
,
for
go fmt
Go 具有类似 -的语法。它支持数组/切片、映射和通道。foreach
遍历数组或切片:
// index and value
for i, v := range slice {}
// index only
for i := range slice {}
// value only
for _, v := range slice {}
遍历地图:
// key and value
for key, value := range theMap {}
// key only
for key := range theMap {}
// value only
for _, value := range theMap {}
在通道上迭代:
for v := range theChan {}
遍历一个通道等同于从通道接收,直到它被关闭:
for {
v, ok := <-theChan
if !ok {
break
}
}
评论
chan
for {v := <-theChan}
ok
for { ... }
实际上,您可以通过对 type 使用 来不引用其返回值:range
for range
arr := make([]uint8, 5)
i,j := 0,0
for range arr {
fmt.Println("Array Loop", i)
i++
}
for range "bytes" {
fmt.Println("String Loop", j)
j++
}
https://play.golang.org/p/XHrHLbJMEd
评论
以下是如何在 Go 中使用 foreach 的示例代码:
package main
import (
"fmt"
)
func main() {
arrayOne := [3]string{"Apple", "Mango", "Banana"}
for index,element := range arrayOne{
fmt.Println(index)
fmt.Println(element)
}
}
这是一个运行示例 https://play.golang.org/p/LXptmH4X_0
评论
这可能是显而易见的,但您可以像这样内联数组:
package main
import (
"fmt"
)
func main() {
for _, element := range [3]string{"a", "b", "c"} {
fmt.Print(element)
}
}
输出:
abc
https://play.golang.org/p/gkKgF3y5nmt
是的,范围:
for 循环的范围形式循环访问切片或映射。
在切片上取范围时,每次迭代返回两个值。第一个是索引,第二个是该索引处的元素的副本。
例:
package main
import "fmt"
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
for i := range pow {
pow[i] = 1 << uint(i) // == 2**i
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
- 您可以通过将 分配给 来跳过索引或值。
_
- 如果只需要索引,请完全删除该值。
,
我刚刚实现了这个库:https://github.com/jose78/go-collection。
以下是如何使用 Foreach 循环的示例:
package main
import (
"fmt"
col "github.com/jose78/go-collection/collections"
)
type user struct {
name string
age int
id int
}
func main() {
newList := col.ListType{user{"Alvaro", 6, 1}, user{"Sofia", 3, 2}}
newList = append(newList, user{"Mon", 0, 3})
newList.Foreach(simpleLoop)
if err := newList.Foreach(simpleLoopWithError); err != nil{
fmt.Printf("This error >>> %v <<< was produced", err )
}
}
var simpleLoop col.FnForeachList = func(mapper interface{}, index int) {
fmt.Printf("%d.- item:%v\n", index, mapper)
}
var simpleLoopWithError col.FnForeachList = func(mapper interface{}, index int) {
if index > 1{
panic(fmt.Sprintf("Error produced with index == %d\n", index))
}
fmt.Printf("%d.- item:%v\n", index, mapper)
}
此执行的结果应为:
0.- item:{Alvaro 6 1}
1.- item:{Sofia 3 2}
2.- item:{Mon 0 3}
0.- item:{Alvaro 6 1}
1.- item:{Sofia 3 2}
Recovered in f Error produced with index == 2
ERROR: Error produced with index == 2
This error >>> Error produced with index == 2
<<< was produced
评论
我看到很多使用范围的例子。只需提醒一下该范围,即可创建您正在迭代的任何内容的副本。如果对 foreach 范围内的内容进行更改,则不会更改原始容器中的值,在这种情况下,您将需要一个传统的 for 循环,其中包含递增的索引和 deference 索引引用。例如:
for i := 0; i < len(arr); i++ {
element := &arr[i]
element.Val = newVal
}
上一个:在 Go 中连接两个切片
下一个:包含切片的方法
评论
range
for