Golang将数组传递给函数并对其进行修改 [英] Golang passing arrays to the function and modifying it
问题描述
这让我有些困惑 - 这并不意味着传递没有引用的数组不应该修改数组本身?让我说明一下:
func main(){
tab:= [] int {1,2,3 }
fmt.Println(标签)
//结果为[1 2 3]
反向(标签)
fmt.Println(标签)
//结果[3 2 1]
}
func reverse(tab [] int){
for i,j:= 0,len(tab)-1;我<焦耳; i,j = i + 1,j-1 {
tab [i],tab [j] = tab [j],tab [i]
}
}
在上面的代码中,数组没有被引用传递,但是反向函数修改了原始数组,所以它的工作原理与C ++程序会做。任何人都可以解释我的区别吗?
PS:对不起,如果这是一个虚拟问题,我完全不熟悉Golang并试图很好地理解基础知识。 >
解释相当简单:没有一个 array 在上面的代码中明确声明或使用。您的选项卡
本地变量和选项卡
参数为 slices 。
在Go中,数组的长度是键入,例如 [3] int
(例如 [2] int
和 [3] int
是2种不同/不同的数组类型)。如果长度不存在(或者显式为 [2] int
或者隐式类似于复合文字 [...] int {1,2,3}
),那么这不是数组类型,但是一个切片类型。
是的,当你读到的时候,数组的值意味着它的所有元素,当它传递(或赋值)时,它的所有元素都被复制。然而,切片只是小描述符,标题,描述数组的连续部分;并且当切片传递(或分配)时,只有这个标题被复制(包含指针),它将指向相同的基础数组。因此,如果修改切片副本的元素,则更改将反映在原始切片中,因为只有一个支持元素的后备数组。
< sup>如果您想完全知道切片标题中的内容,可以查看 reflect.SliceHeader
类型:它是一个 struct
,包含指向片的第一个元素的指针,长度和容量。请阅读以下博客文章,详细解释这一点:
有关更多详细信息,请参阅这些相关问题:
In most languages (like c++) passing arrays result in implicitly passing it by a reference, so any changes to the passed array in the function will result in changing the original one. I am learning Golang, and In the book "The Go Programming Language" by Alan A.A. Donovan and Brian W. Kernighan It is said, that its behaviour is different from other languages - It does not implicitly pass array by reference.
It is confusing me a bit - doesn't that mean that passing an array without the reference should not modify the array itself? Let me illustrate that:
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]
}
}
In code above array is not passed by the reference, but the reverse function modifies the original one, so It works somewhat like C++ program would do. Could anyone explain me the difference?
PS: Sorry if it is a dummy question, I am totally new to the Golang and trying to understand the basics well.
The explanation is rather simple: there isn't a single array declared or used explicitly in your code above. Your tab
local variable and the tab
parameter are slices.
In Go the length of an array is part of the type, e.g. [3]int
(this is true to an extent that for example [2]int
and [3]int
are 2 different / distinct array types). If the length is not present (either explicit like [2]int
or implicit like in the composite literal [...]int{1, 2, 3}
), then that is not an array type but a slice type.
Yes, as you read, an array value means all its elements, and when passed around (or assigned), all its elements are copied. Slices however are just small descriptors, headers, describing a contiguous section of an array; and when slices are passed around (or assigned), only this header is copied (the pointer included), which will point to the same underlying array. And so if you modify the elements of the slice-copy, the changes will be reflected in the original slice as there is only one backing array that holds the elements.
If you want to know what's in a slice header exactly, you may check out the reflect.SliceHeader
type: it's a struct
containing the pointer to the first element of the slice, the length and the capacity of the slice.
Please read the following blog posts which explain this in great details:
Go Slices: usage and internals
Arrays, slices (and strings): The mechanics of 'append'
Also see these related questions for more details:
Are golang slices pass by value?
这篇关于Golang将数组传递给函数并对其进行修改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!