dongxia2068 2016-11-09 19:27
浏览 239
已采纳

Golang将数组传递给函数并对其进行修改

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.

  • 写回答

2条回答 默认 最新

  • dongmi8980 2016-11-09 19:43
    关注

    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:

    Why have arrays in Go?

    Are golang slices pass by value?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)
  • ¥20 matlab yalmip kkt 双层优化问题
  • ¥15 如何在3D高斯飞溅的渲染的场景中获得一个可控的旋转物体