linuxea:go切片公用的副作用(24)

  • 示例说明:

首先,我们创建一个切片,而后将进行赋值到另外一个变量,并且修改,观察发生的变化
定义一个长度为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[

    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)

}
0 分享

您可以选择一种方式赞助本站

支付宝扫码赞助

支付宝扫码赞助

日期: 2019-12-28分类: Golang

标签: Golang

发表评论