Is there a foreach construct in the Go language? Can I iterate over a slice or array using a for?

2

8 Answers

Answer recommended by Go Language

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:

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 _:

for _, element := range someSlice { // element is the element from someSlice for where we are } 

The underscore, _, is the blank identifier, an anonymous placeholder.

4

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 } } 
4

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

1

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?

5

You can in fact use range without referencing its return values by using for range against your type:

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++ } 

2

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.

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 

I have just implemented this library: .

This is an example of how to use the Foreach loop:

package main import ( "fmt" col "" ) 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 

Try this code in playGrounD.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy