blob: c2b6d728c9ae66fa1a02813ff9fe62515430a6f1 [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Range Clauses
2
3Spec: http://golang.org/doc/go_spec.html#For_statements
4
5## Summary
6
sue spencecb617f82015-10-06 15:49:10 +01007A range clause provides a way to iterate over an array, slice, string, map, or channel.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11008
9## Example
10
Amos Wenger7f8db3b2015-11-21 00:56:26 +010011```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110012for k, v := range myMap {
Dave Day0d6986a2014-12-10 15:02:18 +110013 log.Printf("key=%v, value=%v", k, v)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110014}
15
16for v := range myChannel {
Dave Day0d6986a2014-12-10 15:02:18 +110017 log.Printf("value=%v", v)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110018}
19
20for i, v := range myArray {
Dave Day0d6986a2014-12-10 15:02:18 +110021 log.Printf("array value at [%d]=%v", i, v)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110022}
23```
24
25## Reference
26
27If only one value is used on the left of a range expression, it is the 1st value in this table.
28
29| Range expression | 1st value | 2nd value (optional) | notes |
30|:-----------------|:----------|:---------------------|:------|
31| array or slice a ` [n]E `, ` *[n]E `, or ` []E ` | index ` i int ` | ` a[i] ` E |
32| string s string type | index ` i int ` | rune ` int ` | range iterates over Unicode code points, not bytes |
33| map m ` map[K]V ` | key ` k K ` | value ` m[k] ` V |
34| channel c chan E | element ` e E ` | _none_ |
35
36## Gotchas
37
38When iterating over a slice or map of values, one might try this:
39
Amos Wenger7f8db3b2015-11-21 00:56:26 +010040```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110041items := make([]map[int]int, 10)
42for _, item := range items {
43 item = make(map[int]int, 1) // Oops! item is only a copy of the slice element.
44 item[1] = 2 // This 'item' will be lost on the next iteration.
45}
46```
47
48The ` make ` and assignment look like they might work, but the value property of ` range ` (stored here as ` item `) is a _copy_ of the value from ` items `, not a pointer to the value in ` items `. The following will work:
49
Amos Wenger7f8db3b2015-11-21 00:56:26 +010050```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110051items := make([]map[int]int, 10)
52for i := range items {
Dave Day0d6986a2014-12-10 15:02:18 +110053 items[i] = make(map[int]int, 1)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110054 items[i][1] = 2
55}
56```