切片是按值传递的吗? [英] Are slices passed by value?

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

问题描述

在 Go 中,我试图为我的旅行商问题制作一个打乱切片函数.在执行此操作时,我注意到当我开始编辑切片时,我每次传入的加扰功能都不同.

经过一些调试,我发现这是由于我在函数内部编辑了切片.但是由于 Go 应该是一个传递值"语言,这怎么可能?

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

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

解决方案

Go 中的一切都是按值传递的,切片也是如此.但是切片值是一个header,描述了一个后备数组的连续部分,而切片值只包含一个指向实际存储元素的数组的指针.切片值不包括其元素(与数组不同).

因此,当您将切片传递给函数时,将从该标头创建一个副本,包括指向同一个后备数组的指针.修改切片的元素意味着修改后备数组的元素,因此所有共享相同后备数组的切片都会观察"更改.

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

type SliceHeader struct {数据指针长度上限}

查看相关/可能重复的问题:Golang 函数参数是否作为 copy-on-write 传递?

阅读博文:Go Slices:用法和内部结构

In Go, 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 Go 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

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

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