为什么无法通过函数调用修改切片的长度或容量?
问题描述:
我的目的是从特定的层中删除一个元素,并且代码是一样的东西:为什么无法通过函数调用修改切片的长度或容量?
func main() {
s := []int{0, 1, 2, 3, 4}
remove(s, 3)
fmt.Println(s, len(s), cap(s))
}
func remove(s []int, idx int) {
if idx < 0 || idx >= len(s) {
return
}
copy(s[idx:], s[idx+1:])
s = s[:len(s)-1]
fmt.Println(s, len(s), cap(s))
}
但输出显示:
[0 1 2 4] 4 5 [0 1 2 4 4] 5 5
据我所知,切片将被传递到一个函数调用作为引用类型,为什么它不能修改它?
答
切片保持三个值:
1)指针底层数组
2)长度
3)容量
当通过切片于函数时,要传递的副本这三种价值中的一种。因此,您无法更改长度和容量,但由于您有指向底层数组的指针,因此可以更改数组内的值。
答
切片不是指针类型。在引擎盖下片由3个值组成:长度,容量和指向数组的指针。当你通过价值传递它时,你会得到长度和容量的副本 - 你可以为你改变它们。对数组的更改将在该函数外部可见。
如果产生这样的结果
切片是**不是**引用类型,不是真的。 –
此外,可能的重复:[Golang追加一个项目到一个切片](https://*.com/questions/20195296/golang-append-an-item-to-a-slice)。 –
一个切片不是一个引用类型,虽然[它确实使用了一个指针(或者在功能上等同的东西)来避免浪费内存](https://play.golang.org/p/8CBxmyBJjl)。这意味着内存在两个切片之间共享,但长度甚至大小可能不同。他们基本上是两个不同的项目。您可以在Go博客条目“Go Slices:usage and internals”中了解更多关于切片的内容,特别是[本节](https://blog.golang.org/go-slices-usage-and-internals#TOC_4。)。 –