繁体   English   中英

将引用类型“slice”的变量分配给另一个变量,为什么它们不能同时更改?

[英]Assigning a variable of reference type “slice” to another variable, why don't they change simultaneously?

anotherSlice := theSlice
anotherSlice = append(anotherSlice, newEle)
fmt.Println(len(anotherSlice) == len(theSlice))

此代码段将输出false 为什么?

以下是其他一些实验:

package main

import "fmt"

func main() {
    theSlice := []int{3,3,2,5,12,43}
    anotherSlice := theSlice
    fmt.Println(anotherSlice[3], theSlice[3])
    anotherSlice[3] = anotherSlice[3]+2
    fmt.Println(anotherSlice[3], theSlice[3])
    anotherSlice = append(anotherSlice[:3], anotherSlice[4:]...)
    fmt.Println(len(anotherSlice),len(theSlice))
}

输出如下:

5 5
7 7
5 6

Program exited.

每当附加切片时, anotherSlice没有新元素的容量, append函数会创建新切片并返回它。 从那以后,切片anotherSlicetheSlice是不同的 - 它们由单独的数组支持。

重新切割长度较短的切片anotherSlice[:3]对切​​片的原始容量没有影响。

以下行:

anotherSlice = append(anotherSlice[:3], anotherSlice[4:]...)

削减第四(索引3)元素。 因为anotherSlice[:3]具有容纳anotherSlice[4:]所有元素的能力,所以不会发生新的分配,因此两个切片都被修改。

package main

import (
        "fmt"
)   

func main() {
        x := []int{1, 2, 3, 4, 5, 6}
        fmt.Println(cap(x[:3]) >= len(x[:3])+len(x[4:]))
        y := append(x[:3], x[4:]...)
        fmt.Println(x, y)
}

操场

为什么一个切片的长度不跟随另一个切片的长度变化的变化的答案与可能被复制和/或修改的底层存储无关。

在Go中,记住切片是很重要的。 它是一个带有长度字段,容量字段和指向数组的指针的结构。 某些操作会更改长度字段。 有些人改变了容量字段。 有些更改存储在基础数组中的数据。

如果一个人没有掌握如何在语言中实现切片,就会出现各种混乱和错误以及浪费的机会。 一旦人们对切片的实现方式感到满意,它们就非常易于使用,并且编译器能够理解切片的结构,可以编写一些非常优雅且易于读取的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM