当前位置: 首页 > 面试题库 >

Golang切片是否按值传递?

尹乐邦
2023-03-14
问题内容

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

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

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

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


问题答案:

Go中的所有内容都按值传递,也是如此。但是slice值是一个 标头
,描述了后备数组的连续部分,而slice值仅包含指向实际存储元素的数组的指针。slice值不包含其元素(与数组不同)。

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

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

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

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

阅读博客文章:Go Slices:用法和内部原理



 类似资料:
  • 问题内容: 我想知道我什么时候做类似的事情 创建新字符串或返回视图/迭代器 问题答案: Python会进行逐个切片,这意味着每次切片时(非常琐碎的切片(例如)除外),它都会将所有数据复制到一个新的字符串对象中。 根据一位开发人员的说法,之所以做出此选择是因为 [按引用切片]方法更复杂,更难实现并且可能导致意外行为。 例如: 使用“按切片复制”设计,可以立即释放字符串。尽管您只对第一个字符感兴趣,但

  • 问题内容: 如何找出切片的反射值的类型? 以上结果 当我尝试创建错误的切片时会崩溃 例如,而不是因此,我需要在创建反射值之前知道反射值的确切切片类型。 问题答案: 首先,我们需要通过测试来确保我们正在处理切片: 如果没有该检查,您将面临运行时恐慌的风险。因此,既然我们知道我们正在处理切片,则查找元素类型非常简单: 由于我们可能期望许多不同的元素类型,因此可以使用switch语句来区分:

  • 问题内容: 只是一个关于如何在Java中传递参数的快速问题… 在这种情况下,stdout和stderr(用作tidy()中的参数)的值是否会更改为新的StringBuffer(buffer.substring(i))?我的假设是,它们将作为对象变量(对象指针)始终按值传递吗? 问题答案: 您错报了这里发生的事情-对象引用按值传递(创建了引用的副本),因此调用tidy时 不会 修改stdout和st

  • 本文向大家介绍JS是按值传递还是按引用传递,包括了JS是按值传递还是按引用传递的使用技巧和注意事项,需要的朋友参考一下 按值传递 VS. 按引用传递 按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。   按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被

  • 问题内容: 我一直认为Java使用传递引用。 但是,我已经看到了几篇博客文章声称不是(博客文章说Java使用值传递)。 我不认为我能理解他们的区别。 有什么解释? 问题答案: Java总是按值传递。 不幸的是,我们根本不处理任何对象,而是处理称为引用的 对象句柄(当然是通过值传递)。选择的术语和语义很容易使许多初学者感到困惑。 它是这样的: 在上面的示例中仍将返回”Max”。值aDog内main未

  • 我一直认为Java使用按引用传递。 然而,我看到一篇博客文章声称Java使用传递值。 我想我不明白他们的区别。 原因是什么?