gpt4 book ai didi

c++ - Golang 将数组传递给函数并修改它

转载 作者:IT王子 更新时间:2023-10-29 01:51:02 26 4
gpt4 key购买 nike

在大多数语言(如 C++)中,传递数组会导致通过引用隐式传递它,因此对函数中传递的数组的任何更改都将导致更改原始数组。我正在学习 Golang,并且在 Alan A.A. 的《The Go Programming Language》一书中。 Donovan 和 Brian W. Kernighan 据说,它的行为不同于其他语言 - 它不会通过引用隐式传递数组。

这让我有点困惑——这是否意味着传递一个没有引用的数组不应该修改数组本身?让我来说明一下:

func main() {
tab := []int{1, 2, 3}
fmt.Println(tab)
// Results in [1 2 3]
reverse(tab)
fmt.Println(tab)
// Results in [3 2 1]
}

func reverse(tab []int) {
for i, j := 0, len(tab)-1; i < j; i, j = i+1, j-1 {
tab[i], tab[j] = tab[j], tab[i]
}
}

在上面的代码中,数组不是通过引用传递的,而是反向函数修改了原始数组,所以它的工作方式有点像 C++ 程序。谁能给我解释一下区别?

PS:对不起,如果这是一个虚拟问题,我对 Golang 是全新的,并且试图很好地理解基础知识。

最佳答案

解释很简单:没有一个 array在上面的代码中明确声明或使用。您的 tab 局部变量和 tab 参数是 slices .

在 Go 中,数组的长度是类型的一部分,例如[3]int(这在一定程度上是正确的,例如 [2]int[3]int 是 2 个不同/不同的数组类型)。如果长度不存在(显式如 [2]int 或隐式如 composite literal [...]int{1, 2, 3}) , 则不是数组类型而是 slice 类型。

是的,如您所读,数组值表示它的所有元素,并且在传递(或赋值)时,它的所有元素都会被复制。然而, slice 只是小的描述符、标题,描述了数组的连续部分;当 slice 被传递(或分配)时,只有这个头被复制(包括指针),它将指向相同的底层数组。因此,如果您修改 slice 拷贝的元素,更改将反射(reflect)在原始 slice 中,因为只有一个支持数组来保存元素。

如果您想确切地知道 slice header 中的内容,您可以查看 reflect.SliceHeader类型:它是一个结构,包含指向 slice 第一个元素的指针、 slice 的长度和容量。

请阅读以下博客文章,其中详细解释了这一点:

Go Slices: usage and internals

Arrays, slices (and strings): The mechanics of 'append'

另请参阅这些相关问题以获取更多详细信息:

Why have arrays in Go?

Are golang slices pass by value?

关于c++ - Golang 将数组传递给函数并修改它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40514555/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com