将切片传递给Scanf

时间:2017-07-18 10:49:47

标签: go slice

摘录:

package main
import "fmt"

func main() {
    mapIsh := make([]int64, 5)
    fmt.Scanf("%v %v %v %v %v", &mapIsh[0], &mapIsh[1], &mapIsh[2], &mapIsh[3], &mapIsh[4])

    fmt.Print(mapIsh[0], mapIsh[1], mapIsh[2], mapIsh[3], mapIsh[4])
}

我创建一个切片并希望保存读取操作的内容。以上工作如预期。我不知道的是为什么我必须将指针传递给数组元素(我假设值是通过片/数组的引用传递的)。

此外,如果我不将其中一个参数作为指针,则不会读取后续值。所以有人可以解释以下内容:

输入数据:1 2 3 4 5

1)对于:

fmt.Scanf("%v %v %v %v %v", mapIsh[0], mapIsh[1], mapIsh[2], mapIsh[3], mapIsh[4])

我得到:0 0 0 0 0

2)对于:

    fmt.Scanf("%v %v %v %v %v", &mapIsh[0], &mapIsh[1], mapIsh[2], &mapIsh[3], &mapIsh[4])

我得到:1 2 0 0 0

2 个答案:

答案 0 :(得分:2)

参数总是按Go中的值传递,永远不会通过引用传递。

你是正确的,将一个切片传递给一个函数将允许该函数改变它的元素。但是你没有将切片传递给Scanf;你的两个例子是传递int64元素而不是传递这些元素的地址。我认为您对索引语法感到困惑,并且认为mapIsh[0]意味着您传递了函数将能够变异的东西。但mapIsh[0]实际上只是一个int64,是mapIsh的第一个元素。

至于为什么你得到零,因为Go将mapIsh初始化为零值,对于int64s数组全为0。当Scanf无法读入您忘记&的值时,它无法继续。这就是为什么你应该检查从Scanf返回的错误,这将指示错误。

(请注意,按值传递意味着将数组传递给函数会创建该数组的副本,因此该函数将无法像切片那样改变元素。这不是'这里实际上是相关的,如上所述。)

答案 1 :(得分:1)

首先,对于切片/数组,值通过引用传递。

同时,如果您将切片值传递给某个函数,接收器将能够修改相同的基础数组,因为切片值包含指针。

在您的情况下,您不是自己传递切片,而是传递解除引用的int64值的副本。 fmt.Scanf未更新mapIsh。只有传递地址才能使用扫描值。