Arrays 什么';s func foo(arr[]int)int和func foo(arr[num]int)int之间的区别

Arrays 什么';s func foo(arr[]int)int和func foo(arr[num]int)int之间的区别,arrays,go,slice,func,Arrays,Go,Slice,Func,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}

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)
,编译器将报告一个错误,如“不能在foo1的参数中使用arr2(type[]int)作为type[2]int”和“不能在foo2的参数中使用arr1(type[2]int)作为type[]int”


那么,谁能帮我解释一下它们之间的区别,或者给我一些研究的链接呢?提前感谢。

[2]int
是一个固定长度的数组,包含两个条目。
[]int
是一个非固定片

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


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

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

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

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

使用
foo1
调用函数时,将创建数组的副本

因此原始值
arr1
保持不变

[2]int
是一个,
[]int
是一个

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

Go中的所有内容都是按值传递的。我也要切片。但是切片值是一个头,描述了一个支持数组的连续部分,切片值只包含一个指向实际存储元素的数组的指针。切片值不包括其元素(与数组不同)。当您传递一个切片时,只复制切片头(指向同一后备数组),因此修改其元素会修改同一后备数组中的元素,因此调用者将观察更改。在此处阅读更多信息:要查看切片标头中的内容:

与切片不同,数组不是头。一个数组值意味着它的所有元素,所以当你传递一个数组值时,它的所有元素都会被复制,在传递给你的函数中,你只能修改这个复制数组;调用者不会观察对数组所做的更改(例如更改其元素)

请注意,尽管从数组中获取切片值非常容易,但您可以简单地使用:

推荐博文:


更深入地了解数组与切片:

类型为
[2]int的数组有2个元素,而不是3个。学习链接:围棋之旅。常见问题解答。有效的开始。语言规范和博客。这些基本问题在本次旅行中都有详细介绍:两次。
var a [2]int = [2]int{1, 2}
var s []int = a[:]
fmt.Println(s) // Prints [1 2]