Golang将数组传递给函数并修改它
Golang passing arrays to the function and modifying it
在大多数语言(如c++)中,传递数组会导致通过引用隐式地传递数组,因此对函数中传递的数组的任何更改都会导致原始数组的更改。我正在学习Golang,在Alan A.A. Donovan和Brian W. Kernighan的《Go编程语言》一书中,据说,它的行为与其他语言不同-它不会通过引用隐式传递数组。
这让我有点困惑-这是不是意味着传递一个没有引用的数组不应该修改数组本身?让我举例说明:
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]
}
}
在代码中,数组不是由引用传递的,但是反向函数修改了原始数组,所以它的工作方式有点像c++程序。谁能给我解释一下这两者的区别吗?
PS:对不起,如果这是一个假问题,我对Golang完全陌生,并试图很好地理解基础知识。
解释相当简单:在上面的代码中没有显式声明或使用单个数组。您的tab
局部变量和tab
参数是片。
在Go中,数组的长度是类型的一部分,例如[3]int
(这在一定程度上是正确的,例如[2]int
和[3]int
是两个不同的/不同的数组类型)。如果长度不存在(显式的如[2]int
或隐式的如复合字面值[...]int{1, 2, 3}
),那么它不是数组类型,而是切片类型。
是的,正如你读到的,数组值意味着它的所有元素,当传递(或赋值)时,它的所有元素都被复制。然而,切片只是一个小的描述符,头,描述数组的连续部分;当传递(或分配)切片时,只复制这个头(包括指针),它将指向相同的底层数组。因此,如果您修改了切片副本的元素,这些更改将反映在原始切片中,因为只有一个保存这些元素的后备数组。
如果你想确切地知道切片头中有什么,你可以看看reflect.SliceHeader
类型:它是一个struct
类型,包含指向切片第一个元素的指针,切片的长度和容量。
请阅读下面的博客文章,这些文章详细解释了这一点:
Go Slices:用法和内部构造
数组、切片(和字符串):'append'
的机制为什么在Go中有数组?
golang切片是按值传递的吗?
您定义的不是array
,而是一个数组的slice
,该数组通过引用传递,如golang文档中指定的。查看此链接
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何从子成员函数修改父公共成员变量
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- C++ 使用同一函数时如何修改间距
- C++:通过函数修改数组
- 如何调试指针参数是否通过函数修改
- 为什么我可以在C 11中使用const函数修改类
- Qt - 使用λ函数修改先前连接信号的插槽参数
- 如何返回通过memcpy函数修改的两个阵列
- Arduino esp8266中的c++函数修改了c文件中生成的浮点值,在c++函数退出后,c文件中会出现胡言乱语
- 调用带有扭曲的库函数-修改其某些行为
- 二维数组被函数修改后如何删除
- 由算术运算符成员函数修改的动态数组的复制构造函数
- 如何在函数修改堆栈时将堆栈传递给函数
- 当我们可以使用普通函数修改静态数据成员时,静态成员函数的需求是什么?
- 通过函数修改数组的元素
- 挂钩(热补丁)类成员函数.修改虚函数表项
- 为什么引用成员可以被const成员函数修改
- 使用 friend 关键字和使用成员函数修改类内部的私有变量有什么区别
- c++通过一个函数修改多个数组