Golang将数组传递给函数并对其进行修改
在大多数语言(如c ++)中,传递数组会导致通过引用隐式传递它,因此对函数中传递的数组进行的任何更改都将导致更改原始数组。我正在学习Golang,在Alan
AA 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
参数是
slices 。
在Go语言中,数组的长度是该类型的一部分,例如[3]int
(在一定程度上是正确的,[2]int
并且[3]int
是2种不同/不同的数组类型)。如果长度不存在([2]int
在复合文字中
像显式一样或隐式一样[...]int{1, 2, 3}
),则该长度不是数组类型,而是切片类型。
是的,当您阅读时,数组值表示其所有元素,并且在传递(或分配)时会复制其所有元素。切片不过是小的描述符,标头,描述了数组的连续部分。当切片被传递(或分配)时,仅复制此标头(包括指针),该标头指向相同的基础数组。因此,如果您修改切片副本的元素,则更改将反映在原始切片中,因为只有一个支持该元素的后备阵列。
如果您想确切地了解切片头中的内容,则可以检查reflect.SliceHeader
类型:它struct
包含指向切片第一个元素的指针,切片的长度和容量。
切成薄片:用法和内部原理
数组,切片(和字符串):“追加”的机制
以上是 Golang将数组传递给函数并对其进行修改 的全部内容, 来源链接: utcz.com/qa/434187.html