Reputation: 34145
Consider the following code which just prints all the ENV vars
package main
import (
"fmt"
"os"
)
func main() {
for i, env := range os.Environ() {
fmt.Println(i, env)
}
}
Here, os.Environ() is supposed to return array of strings([] string), to loop over it. I need to to use range keyword & also for loop. Question is:
[]string
is already an array & we can iterate over arrays right?range
do? and what does for
loop does?Sorry if this question is too stupid, I am just starting with Go
Upvotes: 6
Views: 6086
Reputation: 38907
I find the accepted answer slightly confusing as it doesn't directly directly address the questions.
So to answer your questions.
for range
is one loop style you can use to access the elements in the environment slice returned from os.Environ(), but as I show below you can use the other for loop style. You will see the differences below.range
in this for loop is the construct you use that will provide a copy and the index for each of the elements in the slice.To summarize, there are basically two forms of the for loop construct in go (actually 3, but we're only concerned with two here).
One uses the range
keyword, and the other does not.
The for ... range
version creates a copy of the item in the slice you are iterating over. The other, does not and you must access it by reference.
func main() {
for i, env := range os.Environ() {
fmt.Println(i, env)
}
}
Here is how you would write the for loop without using range construct:
func main() {
env := os.Environ()
for i := 0; i < len(env); i++ {
fmt.Println(i, env[i])
}
}
I also found a third option which looks tidy and has the same advantage as option 2.
func main() {
env := os.Environ()
for i := range env {
fmt.Println(i, env[i])
}
}
The first approach is nice and clean, but the second provides better performance because it doesn't do a copy. Both have their place. I would generally use range
, but where you need it, the traditional C-like loop is available.
Note: Whenever you are dealing with strings you should always use the range loop as it will return a rune instead of a char. This is particularly important when dealing with internationalisation. See this blog post about string iteration here: Strings, bytes, runes and characters in Go
Upvotes: 2
Reputation: 39
One notable difference if for range creates copy of each the objects from slice/array. Have a look at following code snippet. https://go.dev/play/p/MHaCXj-Y5WD
Upvotes: 1
Reputation: 1324576
As mentioned in Range Clauses:
A range clause provides a way to iterate over a array, slice, string, map, or channel.
If you want to iterate over an []string
, you need range
.
A For statement doesn't always use range.
ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
You have:
In its simplest form, a "
for
" statement specifies the repeated execution of a block as long as a boolean condition evaluates to trueA "for" statement with a
ForClause
is also controlled by its condition, but additionally it may specify an init and a post statement, such as an assignment, an increment or decrement statementA "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 if present and then executes the block.
Upvotes: 8