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

use*_*252 2 arrays func go slice

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
}
Run Code Online (Sandbox Code Playgroud)

我还发现,如果我使用foo1(arr2)或者foo2(arr1),编译器会报告错误,例如"不能使用arr2(type [] int)作为类型[2] int参数foo1""不能使用arr1(类型[2] int)作为类型参数foo2中的[] int".

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

icz*_*cza 5

[2]int是一个数组,[]int是一个切片.

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

Go中的所有内容都按值传递.切片也是.但切片值是标题,描述了支持数组的连续部分,切片值仅包含指向实际存储元素的数组的指针.切片值不包括其元素(与数组不同).传递切片时,仅复制切片标头(指向同一支持数组),因此修改其元素会修改同一支持数组中的元素,因此调用者将观察更改.在这里阅读更多相关信息:Golang切片是否通过值传递?要查看切片标题中的内容:reflect.SliceHeader.

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

请注意,从阵列中获取切片值非常容易,您可以简单地使用切片:

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

推荐博客文章:Go Slices:用法和内部

更深入地了解数组与切片:为什么Go中的数组?