如何在for循环中结合多个赋值和范围?

huangapple go评论87阅读模式
英文:

How to combine multiple assignment and Range in for loops

问题

我正在尝试弄清楚如何在Golang中组合多个赋值和范围(或者是否可能)。

以下是我想要做的伪代码示例:

files := [2]*os.File{}

for i, _, fileName := range os.Args[1:3] {
  files[i], _ = os.Open(fileName)
}

我的想法是我想同时拥有迭代计数器(i)和文件名(fileName)。我知道可以通过使用范围的键和一些数学运算(key - 1)来实现这一点,但这不是示例的重点。

编辑:

在调试上面的示例时,我了解到在该示例中,i的范围是0-1;因为os.Args[1:2]是一个切片,该切片的索引是0-1。因此,我不需要使用"some math"来正确索引键。

编辑2:
这篇文章也是必读的,它解释了为什么上面的[2]*os.File{}不是Go语言的惯用写法,而应该不指定大小(files := []*os.File{}),这样files的类型就是[]*os.File

英文:

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

答案1

得分: 5

这里有很多不同的问题。首先,range已经可以实现你想要的功能,不需要进行任何数学计算。

for i, fileName := range os.Args[1:] {

在这里,i的范围将从0到1,就像你想要的一样。对切片进行迭代总是从索引0开始(相对于切片的起始位置)。(http://play.golang.org/p/qlVM6Y7yPD)

请注意,os.Args[1:2]只是一个元素。你可能想要的是两个元素。

无论如何,这可能是你真正想要的:

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\n", files)

在Go语言中,固定长度的数组非常不常见。通常你会使用make函数创建一个切片。

英文:

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\n", files)

Fixed-length arrays are very uncommon in Go. Generally you want a slice, created with make.

答案2

得分: 3

例如,

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 {
			// 处理错误
		}
	}
	fmt.Println(files)
}

输出:

$ go build so.go && ./so no.go so.go to.go
[<nil> 0xc820030020]
$
英文:

For example,

so.go:

package main

import (
	&quot;fmt&quot;
	&quot;os&quot;
)

func main() {
	files := [2]*os.File{}
	for i, fileName := range os.Args[1:] {
		if i &gt;= 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 &amp;&amp; ./so no.go so.go to.go
[&lt;nil&gt; 0xc820030020]
$ 

huangapple
  • 本文由 发表于 2015年12月1日 02:36:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/34005573.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定