2017-06-23 158 views
2

func foo(arr []int) intfunc foo(arr [*num*]int) int有什么区别?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)foo2(arr1)我还发现,该编译器将报告等一个错误“不能使用ARR2(类型[] INT)作为型[2] INT在foo1“”的参数中,在参数foo2“”中,不能使用arr1(类型[2] int)作为类型[] int的参数。

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

+1

学习的链接:Tour of Go https://tour.golang.org/welcome/1。常见问题https://golang.org/doc/faq。有效转到https://golang.org/doc/effective_go.html。语言规范https://golang.org/ref/spec和博客https://blog.golang.org/。这个基本问题在巡回赛中都有详细的介绍:两次。 – Volker

回答

5

[2]intarray[]intslice

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

Go中的所有内容都是按值传递的。切片也是。但是切片值是一个标头,描述了一个支持数组的连续部分,并且切片值只包含一个指向实际存储元素的数组的指针。切片值不包含其元素(与数组不同)。当你传递一个切片时,只有切片头被复制(指向相同的后备数组),因此修改其元素会修改同一个后备数组中的元素,因此调用者将观察这些变化。阅读更多关于此处的信息:Are golang slices pass by value?查看切片标题中的内容:reflect.SliceHeader。与片不同,数组不是片段。一个数组值意味着它的所有元素,所以当你传递一个数组值时,它的所有元素都被复制,并且在它传递给函数的内部,你只能修改这个拷贝数组;调用者不会观察对数组所做的更改(例如,更改其元素)。

注意,但它是很容易获得的数组切片值,你可以简单地使用slicing

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

推荐的博客文章:Go Slices: usage and internals

更深入地了解数组VS片:Why have arrays in Go?

+0

感谢您的信息和链接。 – user3300252

0

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

func foo1(arr [2]int)需要一个固定长度 int有2个条目的数组。 func foo2(arr []int)需要一个非固定的 int与任意数量的条目。

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

+1

“[2] int”类型的数组有2个元素,而不是3. – icza

0

[n]T类型是n类型值的数组,T

[]T类型是T类型的元素的切片。

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

随着foo1该函数被调用时,数组的副本。

所以原值arr1保持不变

相关问题