Golang切片是否按值传递? [英] Are golang slices passed by value?

查看:298
本文介绍了Golang切片是否按值传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Golang中,我试图为我的旅行推销员问题创建一个加扰切片函数.在执行此操作时,我注意到,当我开始编辑切片时,每次传递时,我赋予的加密功能都是不同的.

经过一些调试后,我发现这是由于我在函数内部编辑了切片.但是既然Golang被认为是一种通过价值传递"的语言,那怎么可能呢?

https://play.golang.org/p/mMivoH0TuV

我提供了一个游乐场链接来显示我的意思. 通过删除第27行,您得到的输出与留在其中的输出将有所不同,这应该不会有所不同,因为该函数在作为参数传入时应该具有自己的切片副本.
有人可以解释这种现象吗?

解决方案

Go中的所有内容均按值传递,也进行切片.但是slice值是 header ,描述了后备数组的连续部分,slice值仅包含指向实际存储元素的数组的指针. slice值不包含其元素(与数组不同).

因此,当您将切片传递给函数时,将从该标头(包括指针)进行复制,该指针将指向相同的后备数组.修改切片的元素意味着修改了后备数组的元素,因此所有共享同一后备数组的切片将观察"更改.

要查看切片标题中的内容,请检出 reflect.SliceHeader 类型:

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

请参阅相关/可能重复的问题: Golang函数参数是否以写时复制形式传递?

阅读博客文章:切片段:用法和内部知识

In Golang, I am trying to make a scramble slice function for my traveling salesman problem. While doing this I noticed when I started editing the slice I gave the scramble function was different every time I passed it in.

After some debugging I found out it was due to me editing the slice inside the function. But since Golang is supposed to be a "pass by value" language, how is this possible?

https://play.golang.org/p/mMivoH0TuV

I have provided a playground link to show what I mean. By removing line 27 you get a different output than leaving it in, this should not make a difference since the function is supposed to make its own copy of the slice when passed in as an argument.
Can someone explain the phenomenon?

解决方案

Everything in Go is passed by value, slices too. But a slice value is a header, describing a contiguous section of a backing array, and a slice value only contains a pointer to the array where the elements are actually stored. The slice value does not include its elements (unlike arrays).

So when you pass a slice to a function, a copy will be made from this header, including the pointer, which will point to the same backing array. Modifying the elements of the slice implies modifying the elements of the backing array, and so all slices which share the same backing array will "observe" the change.

To see what's in a slice header, check out the reflect.SliceHeader type:

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

See related / possible duplicate question: Are Golang function parameter passed as copy-on-write?

Read blog post: Go Slices: usage and internals

这篇关于Golang切片是否按值传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆