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

- 4,387
- 2
- 22
- 35

- 25,149
- 14
- 39
- 40
-
1check out: http://groups.google.com/group/golang-nuts/browse_thread/thread/e2966ccdfe910e14?pli=1 – Kakashi Oct 16 '11 at 05:19
-
2The usage of `range` in `for` loops is also mentioned in the "An Interlude about Types" section (towards its end) of the Go tutorial. – kostix Oct 16 '11 at 12:31
9 Answers
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.

- 30,738
- 21
- 105
- 131

- 254,901
- 44
- 429
- 631
-
25In this example, `element` is the *value* of the element (a copy) -- it is not the element itself. Although you can assign to `element`, this will not effect the underlying sequence. – Brent Bradburn Dec 08 '18 at 20:15
-
I know in Python and C it's frequent to use underscore as a function for localization ( i.e. the [gettext](https://docs.python.org/3/library/gettext.html#localizing-your-module) ). Would the use of underscore cause any problems in Go ? Does Go even use the same library for localization ? – Sergiy Kolodyazhnyy Dec 29 '18 at 09:05
-
4@SergiyKolodyazhnyy Py docs says "(gettext) function is usually aliased as `_()` in the local namespace" which is just _by convention_, it's not part of the localization lib. The underscore `_` is a valid label, and it's also convention in Go (and Python and Scala and other langs) to assign to `_` for return values you won't use. The scope of `_` in this example is restricted to the body of the `for` loop. If you have a package-scoped function `_` then it would be shadowed inside the scope of the for loop. There's a few packages for localization, I've not seen any use `_` as a function name. – Davos Apr 05 '19 at 15:40
-
See [Moshe Revah's answer](https://stackoverflow.com/a/34333832/1365918) below for more usage examples of `for...range`. Includes slices, maps and channels. – kapad Sep 08 '20 at 08:33
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
}
}
-
21Although the OP only asked for slice usage, I prefer this answer, because most will eventually need the other usages as well. – domoarigato Aug 02 '16 at 01:36
-
4important distinction about the `chan` usage: ranging over a channel will gracefully exit the loop if the writer closes the channel at some point. In the `for {v := <-theChan}` _equivalent_, it will *not* exit on channel close. You can test for this via the second `ok` return value. [TOUR EXAMPLE](https://tour.golang.org/concurrency/4) – colm.anseo Oct 10 '17 at 22:25
-
Thought the same when reading it, `for { ... }` stands for an infinite loop. – Levite Dec 22 '17 at 09:44
-
How about just for without both key, value.I just want to run specific len. And do nothing with array. Ex: for _ := range slice{} – Duong Phan Mar 22 '22 at 14:48
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

- 30,738
- 21
- 105
- 131

- 7,237
- 4
- 28
- 34
-
2Sometimes it's the simplest example that is the most useful. Thanks! I've got nothing against the most esoteric answers from the other commenters — they certainly illustrate the intricacies of very idiomatic Go programming, to the point that they become... unreadable and hard to follow — but I prefer your answer: it goes straight to the core with the simplest possible example (which works and it's obvious why it works). – Gwyneth Llewelyn Jun 11 '20 at 22:03
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.

- 30,738
- 21
- 105
- 131

- 14,264
- 6
- 62
- 62
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?

- 21,900
- 13
- 104
- 178
-
3Add a `,` and it's clearer where the `for` condition ends: http://play.golang.org/p/pcRg6WdxBd - This is actually the first time I've found a counter argument to the `go fmt` style, thanks! – topskip Jul 07 '14 at 09:35
-
-
@FilipHaglund It is not the point if it is valid. The point is that IMO it's clearer where the for condition ends in that particular case above. – topskip Jun 14 '15 at 07:15
-
12In my opinion, this answer is unreasonably complex for the targeted question. – AndreasHassing Feb 02 '16 at 22:08
-
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++
}

- 30,738
- 21
- 105
- 131

- 6,893
- 2
- 41
- 40
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

- 7,941
- 3
- 37
- 50
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
}

- 11
- 1
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

- 30,738
- 21
- 105
- 131

- 21
- 6
-
How is it a for-each loop? Isn't it just list processing? Can you [elaborate](https://stackoverflow.com/posts/63549127/edit) in your answer? (But ***without*** "Edit:", "Update:", or similar - the question/answer should appear as if it was written today.) – Peter Mortensen May 23 '22 at 13:29