2017-07-18 91 views
0

的片段:传递切片SCANF

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

+1

添加错误检查。在某些情况下,您的示例会产生错误“预期的整数” –

+1

另外,我已经为格式化字符串添加了'\ n',并且错误消失了。 –

回答

1

首先,值为而不是通过切片/数组的参考传递。

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

对于您的情况,您并未传递片段本身,而是取消引用的int64值的副本。并且fmt.Scanf未更新mapIsh。只有通过地址才能使用扫描值。

+0

Tnx。这就说得通了。我想我是一个例子,其中一个int通过引用传递给scanf –

2

参数总是按Go中的值传递,绝不参考。

你说的正确,将一个切片传递给一个函数将允许该函数改变其元素。但是你没有通过Scanf;你的两个例子传入了int64元素而不是传入这些元素的地址。我认为你会被索引语法弄糊涂,并认为mapIsh[0]在某种程度上意味着你传递了一些函数将会发生变异的东西。但mapIsh[0]真的只是一个int64,mapIsh的第一个元素。

至于你为什么要得到零,那是因为Go初始化mapIsh为zero-value,对于int64s数组全为0。当Scanf无法读入您忘记&的值时,无法继续。这就是为什么你应该检查从Scanf返回的错误,这将表明错误。 (请注意,传递值意味着将数组传递给函数会创建该数组的副本,因此该函数将无法像切片一样对元素进行变异,但实际上并不是这样如上所述。)

+0

感谢,我间隔和添加“或数组”没有思考。现在修复,并在最后添加注释。 –

+0

太棒了,我已经删除了我的评论现在毫无意义。 –