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。
那么谁可以帮助解释他们之间的区别或给我一些学习的链接?提前谢谢。
答案 0 :(得分:5)
数组和切片是完全不同的类型:您无法传递需要切片的数组,并且您无法通过需要数组的切片。由于长度是数组类型的一部分,因此您甚至不能使用长度不同的数组值,例如:您无法将[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]T
是n
类型的T
数组。
类型[]T
是一个包含T
类型元素的切片。
数组具有固定大小。切片是动态的。
使用foo1
,在调用函数时会生成数组的副本。
因此原始值arr1
保持不变