- 示例说明:
首先,我们创建一个切片,而后将进行赋值到另外一个变量,并且修改,观察发生的变化定义一个长度为3,容量为5的int类型的nums切片
nums := make([]int,3,5)
在声明一个nums02,nums02是从nums的切片生成的,start 1,end 3
nums02 := nums[1:3]
而后打印下两个变量的结果。
fmt.Println(nums,nums02)
如下。我们没有赋值,nums是三个0和nums02两个0
[root@www.linuxea.com /opt/Golang/work2]# go run make6.go
[0 0 0] [0 0]
为了看出效果,我们修改nums02的索引0等于1,而后在打印nums02和nums
nums02[0] = 1
fmt.Println(nums,nums02)
运行如下:
[root@www.linuxea.com /opt/Golang/work2]# go run make6.go
[0 0 0] [0 0]
[0 1 0] [1 0]
- 图解
在go中,nums02是用nums生成的[1:3],nums02和nums公用一个底层数组,这样一来,nums02指向的位置就是nums的索引1和索引3。如下图
nums本身长度是3,表现为三个0。当nums02[0] = 1
的时候,在修改nums02索引0等于1的同时,由于nums02和nums公用一个底层数组,打印nums,nums02
的结果就是[0 1 0] [1 0]
。在进行追加修改如下:
- 如果此时给nums02 追加一个数。如下:
nums02 = append(nums02,3)
fmt.Println(nums,nums02)
而后运行,得到的结果如下:
[0 1 0] [1 0 3]
这是因为nums本身长度为3,nums02追加的3不在nums长度范围内,所以nums中没有nums02追加的3。为了验证,我们在给nums追加一个5。这样一来,nums的长度从3变成了4,索引3位置将会发生改变。如下:
nums = append(nums,5)
fmt.Println(nums,nums02)
运行
[0 1 0 5] [1 0 5]
这时候你会发现刚才nums02追加的3变成了5。这也是因为nums,nums02公用底层的数组导致。
这就是两个切片公用底层的数组的副作用。而这种情况一直会持续到容量不够用重新申请新的底层数组。
并且这种副作用也会延伸到数组中。如下:
定义一个数组
arrays := []int{1,2,3,4,5}
fmt.Println(arrays)
赋值给nums,index省略表示len和cap
nums = arrays[:]
fmt.Println(nums,arrays)
而后修改nums[0]等于100
nums[0] = 100
fmt.Println(nums,arrays)
运行
[root@www.linuxea.com /opt/Golang/work2]# go run make6.go
[0 0 0] [0 0]
[0 1 0] [1 0]
[0 1 0] [1 0 3]
[0 1 0 5] [1 0 5]
[1 2 3 4 5]
[1 2 3 4 5] [1 2 3 4 5]
[100 2 3 4 5] [100 2 3 4 5]
由此可见,对数组也是有 影响的。这是因为在切片的时候原理是一样的。
代码块
[root@www.linuxea.com /opt/Golang/work2]# cat make6.go package main import "fmt" func main(){ nums := make([]int,3,5) nums02 := nums[1:3] fmt.Println(nums,nums02) nums02[0] = 1 fmt.Println(nums,nums02) nums02 = append(nums02,3) fmt.Println(nums,nums02) nums = append(nums,5) fmt.Println(nums,nums02) arrays := []int{1,2,3,4,5} fmt.Println(arrays) nums = arrays[:] fmt.Println(nums,arrays) nums[0] = 100 fmt.Println(nums,arrays) }