2016-04-27 53 views
1
anotherSlice := theSlice 
anotherSlice = append(anotherSlice, newEle) 
fmt.Println(len(anotherSlice) == len(theSlice)) 

这段代码将输出false。为什么?将引用类型“slice”的变量赋值给另一个变量,为什么它们不同时变化?

这里有一些其他的实验:

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. 

回答

2

每当附加片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) 
} 

Playground

+0

我试过别的东西来缩小长度,这个过程在帖子中更新。那是因为在缩小之后,anotherSlice'也缩小到了5? –

1

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

在Go中,重要的是要记住切片是什么。它是一个带有长度字段,容量字段和指向数组的指针的结构。一些操作 更改长度字段。一些更改容量字段。一些更改存储在底层数组中的数据。

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

相关问题