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

2023年 7月 15日 32.3k 0

请输入图片描述

  • 示例说明:

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

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)

}

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论