为什么无法通过函数调用修改切片的长度或容量?

问题描述:

我的目的是从特定的层中删除一个元素,并且代码是一样的东西:为什么无法通过函数调用修改切片的长度或容量?

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

据我所知,切片将被传递到一个函数调用作为引用类型,为什么它不能修改它?

+5

切片是**不是**引用类型,不是真的。 –

+1

此外,可能的重复:[Golang追加一个项目到一个切片](https://*.com/questions/20195296/golang-append-an-item-to-a-slice)。 –

+0

一个切片不是一个引用类型,虽然[它确实使用了一个指针(或者在功能上等同的东西)来避免浪费内存](https://play.golang.org/p/8CBxmyBJjl)。这意味着内存在两个切片之间共享,但长度甚至大小可能不同。他们基本上是两个不同的项目。您可以在Go博客条目“Go Slices:usage and internals”中了解更多关于切片的内容,特别是[本节](https://blog.golang.org/go-slices-usage-and-internals#TOC_4。)。 –

切片保持三个值:

1)指针底层数组

2)长度

3)容量

当通过切片于函数时,要传递的副本这三种价值中的一种。因此,您无法更改长度和容量,但由于您有指向底层数组的指针,因此可以更改数组内的值。

切片不是指针类型。在引擎盖下片由3个值组成:长度,容量和指向数组的指针。当你通过价值传递它时,你会得到长度和容量的副本 - 你可以为你改变它们。对数组的更改将在该函数外部可见。

如果产生这样的结果