英文:
Is there a foreach loop in Go?
问题
在Go语言中有foreach
结构吗?我可以使用for
循环遍历切片或数组吗?
英文:
Is there a foreach
construct in the Go language?
Can I iterate over a slice or array using a for
?
答案1
得分: 1103
从*带有range子句的for语句*:
> 带有“range”子句的“for”语句遍历数组、切片、字符串或映射的所有条目,或在通道上接收的值。
> 对于每个条目,它将迭代值分配给相应的迭代变量,然后执行代码块。
例如:
<!-- language: lang-golang -->
for index, element := range someSlice {
// index是我们所在的索引
// element是someSlice中我们所在位置的元素
}
如果您不关心索引,可以使用_
:
<!-- language: lang-golang -->
for _, element := range someSlice {
// element是someSlice中我们所在位置的元素
}
下划线_
是空白标识符,一个匿名占位符。
英文:
From For statements with range clause:
> A "for" statement with a "range" clause iterates through all entries
> of an array, slice, string or map, or values received on a channel.
> For each entry it assigns iteration values to corresponding iteration
> variables and then executes the block.
As an example:
<!-- language: lang-golang -->
for index, element := range someSlice {
// index is the index where we are
// element is the element from someSlice for where we are
}
If you don't care about the index, you can use _
:
<!-- language: lang-golang -->
for _, element := range someSlice {
// element is the element from someSlice for where we are
}
The underscore, _
, is the blank identifier, an anonymous placeholder.
答案2
得分: 224
Go有一种类似于foreach
的语法。它支持数组/切片、映射和通道。
遍历数组或切片:
// 索引和值
for i, v := range slice {}
// 仅索引
for i := range slice {}
// 仅值
for _, v := range slice {}
遍历映射:
// 键和值
for key, value := range theMap {}
// 仅键
for key := range theMap {}
// 仅值
for _, value := range theMap {}
遍历通道:
for v := range theChan {}
遍历通道等同于从通道接收数据,直到通道关闭:
for {
v, ok := <-theChan
if !ok {
break
}
}
英文:
Go has a foreach
-like syntax. It supports arrays/slices, maps and channels.
Iterate over an array or a slice:
// index and value
for i, v := range slice {}
// index only
for i := range slice {}
// value only
for _, v := range slice {}
Iterate over a map:
// key and value
for key, value := range theMap {}
// key only
for key := range theMap {}
// value only
for _, value := range theMap {}
Iterate over a channel:
for v := range theChan {}
Iterating over a channel is equivalent to receiving from a channel until it is closed:
for {
v, ok := <-theChan
if !ok {
break
}
}
答案3
得分: 23
以下是在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
英文:
Following is the example code for how to use foreach in Go:
package main
import (
"fmt"
)
func main() {
arrayOne := [3]string{"Apple", "Mango", "Banana"}
for index,element := range arrayOne{
fmt.Println(index)
fmt.Println(element)
}
}
This is a running example https://play.golang.org/p/LXptmH4X_0
答案4
得分: 14
是的,range:
for 循环的 range 形式可以迭代一个切片或映射。
当迭代一个切片时,每次迭代会返回两个值。第一个是索引,第二个是该索引处元素的副本。
示例:
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)
}
}
- 通过将值赋给
_
,可以跳过索引或值。 - 如果只想要索引,完全省略
,
后面的值。
英文:
Yes, range:
The range form of the for loop iterates over a slice or map.
When ranging over a slice, two values are returned for each iteration. The first is the index, and the second is a copy of the element at that index.
Example:
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)
}
}
- You can skip the index or value by assigning to
_
. - If you only want the index, drop the
,
value entirely.
答案5
得分: 13
以下示例展示了如何在for
循环中使用range
运算符来实现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;
}
该示例遍历一个函数数组,以统一处理函数的错误。完整示例可在Google的playground中找到。
PS:它还显示了悬挂括号对于代码的可读性是一个不好的主意。提示:for
条件在action()
调用之前结束。显而易见,不是吗?
英文:
The following example shows how to use the range
operator in a for
loop to implement a foreach
loop.
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;
}
The example iterates over an array of functions to unify the error handling for the functions. A complete example is at Google´s playground.
PS: it shows also that hanging braces are a bad idea for the readability of code. Hint: the for
condition ends just before the action()
call. Obvious, isn't it?
答案6
得分: 12
你实际上可以使用range
而不引用其返回值,通过对你的类型使用for range
:
<!-- language: lang-go -->
arr := make([]uint8, 5)
i,j := 0,0
for range arr {
fmt.Println("数组循环", i)
i++
}
for range "bytes" {
fmt.Println("字符串循环", j)
j++
}
https://play.golang.org/p/XHrHLbJMEd
英文:
You can in fact use range
without referencing its return values by using for range
against your type:
<!-- language: lang-go -->
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++
}
答案7
得分: 1
这可能很明显,但你可以像这样内联数组:
package main
import (
"fmt"
)
func main() {
for _, element := range [3]string{"a", "b", "c"} {
fmt.Print(element)
}
}
输出:
abc
https://play.golang.org/p/gkKgF3y5nmt
英文:
This may be obvious, but you can inline the array like so:
package main
import (
"fmt"
)
func main() {
for _, element := range [3]string{"a", "b", "c"} {
fmt.Print(element)
}
}
outputs:
abc
答案8
得分: 1
我看到很多使用range的例子。提醒一下,range会创建一个迭代对象的副本。如果你在foreach循环中对副本进行更改,那么原始容器中的值不会改变,这种情况下你需要使用传统的for循环,通过索引递增并解引用索引引用。例如:
for i := 0; i < len(arr); i++ {
element := &arr[i]
element.Val = newVal
}
英文:
I'm seeing a lot of examples using range. Just a heads up that range creates a copy of whatever you're iterating over. If you make changes to the contents in a foreach range you will not be changing the values in the original container, in that case you'll need a traditional for loop with an index you increment and deference indexed reference. E.g.:
for i := 0; i < len(arr); i++ {
element := &arr[i]
element.Val = newVal
}
答案9
得分: 0
我刚刚实现了这个库: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
英文:
I have just implemented this library: https://github.com/jose78/go-collection.
This is an example of how to use the Foreach loop:
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)
}
The result of this execution should be:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论