func foo(arr [] int)int和func foo(arr [num] int)int之间有什么区别

时间:2017-06-23 08:01:09

标签: arrays go slice func

Scala> val sqlContext = new org.apache.spark.sql.SQLContext(sc) Scala> val employee = sqlContext.read.json(“emplaoyee”) Scala> employee.write.parquet(“employee.parquet”) func foo(arr []int) int之间有什么区别?

以下是两个例子:

func foo(arr [*num*]int) int

我还发现,如果我使用func foo1(arr [2]int) int { arr[0] = 1 return 0 } func foo2(arr []int) int { arr[0] = 1 return 0 } func main() { var arr1 = [2]int{3, 4} var arr2 = []int{3, 4} foo1(arr1) println(arr1[0]) // result is 3, so arr in foo1(arr) is a copy foo2(arr2) println(arr2[0]) // result is 1, so arr in foo2(arr) is not a copy, it is a reference } foo1(arr2),编译器将报告错误,如“不能使用arr2(type [] int)作为参数中的类型[2] int foo1“”不能在参数foo2“中使用arr1(type [2] int)作为类型[] int。

那么谁可以帮助解释他们之间的区别或给我一些学习的链接?提前谢谢。

3 个答案:

答案 0 :(得分:5)

[2]intarray[]intslice

数组和切片是完全不同的类型:您无法传递需要切片的数组,并且您无法通过需要数组的切片。由于长度是数组类型的一部分,因此您甚至不能使用长度不同的数组值,例如:您无法将[3]int类型的数组值用于需要[2]int的内容。

Go中的所有内容都按值传递。切片也是。但切片值是标头,描述了支持数组的连续部分,切片值仅包含指向实际存储元素的数组的指针。切片值不包括其元素(与数组不同)。传递切片时,仅复制切片标头(指向同一支持数组),因此修改其元素会修改同一支持数组中的元素,因此调用者将观察更改。请在此处详细了解相关内容:Are golang slices pass by value?要查看切片标题中的内容:reflect.SliceHeader

与slice不同,数组不是标题。数组值表示其所有元素,因此当您传递数组值时,会复制其所有元素,并且在传递给它的函数内部只能修改此副本数组;调用者不会观察对数组所做的更改(例如更改其元素)。

请注意,从阵列中获取切片值非常容易,您只需使用slicing

var a [2]int = [2]int{1, 2}
var s []int = a[:]
fmt.Println(s) // Prints [1 2]

推荐博文:Go Slices: usage and internals

更深入了解数组与切片:Why have arrays in Go?

答案 1 :(得分:0)

[2]int是一个固定长度的数组,有2个条目 []int是一个不固定的切片。

func foo1(arr [2]int)需要一个包含2个条目的固定长度 int数组。 func foo2(arr []int)使用任意数量的条目获取非固定切片。

它们看起来很相似,但如果你认为[2] int和[] int是完全不同的结构,它可能会有所帮助。

答案 2 :(得分:0)

类型[n]Tn类型的T数组。

类型[]T是一个包含T类型元素的切片。

数组具有固定大小。切片是动态的。

使用foo1,在调用函数时会生成数组的副本。

因此原始值arr1保持不变