I'm trying to figure out how to (or if it's possible to) combine multiple assignment and ranges in Golang
ex pseudo code of what I'd like to do
files := [2]*os.File{}
for i, _, fileName := 0, range os.Args[1:3] {
files[i], _ = os.Open(fileName)
}
The idea being I want to have both an iteration counter (i
) and the filenames (fileName
). I know this can be achieved by using the key from range and some math (key -1
), thats not the point of the example.
Edit:
Upon debugging the above example, I learned that i
will range 0-1 in that example; Because os.Args[1:2] is a slice and that slice has indexing 0-1 . Therefore I dont need "some math" to properly index the keys.
** EDIT 2: ** This post is also a must read as to why the above [2]*os.File{}
is not idiomatic go, instead it should not have a size specified (files := []*os.File{}
) so that files
is of type slice of *os.File
There are a lot of different issues here. First, range
already does what you want. There's no need for even math.
for i, fileName := range os.Args[1:] {
i
will range from 0 to 1 here, just like you want. Ranging over a slice always starts at index 0 (it's relative to the start of the slice). (http://play.golang.org/p/qlVM6Y7yPD)
Note that os.Args[1:2]
is just one element. You probably meant it to be two.
In any case, this is likely what you really meant:
http://play.golang.org/p/G4yfkKrEe7
files := make([]*os.File, 0)
for _, fileName := range os.Args[1:] {
f, err := os.Open(fileName)
if err != nil {
log.Fatalf("Could not open file: %v", err)
}
files = append(files, f)
}
fmt.Printf("%v
", files)
Fixed-length arrays are very uncommon in Go. Generally you want a slice, created with make
.
For example,
so.go
:
package main
import (
"fmt"
"os"
)
func main() {
files := [2]*os.File{}
for i, fileName := range os.Args[1:] {
if i >= len(files) {
break
}
var err error
files[i], err = os.Open(fileName)
if err != nil {
// handle error
}
}
fmt.Println(files)
}
Output:
$ go build so.go && ./so no.go so.go to.go
[<nil> 0xc820030020]
$