go多维切片和切片与数组的区别(26)

2023年 7月 15日 38.0k 0

请输入图片描述

  • 二维切片

1多维切片定义

使用两个括号定义二维切片

[][]int{}
points := [][]int{}

2多维切片赋值

points = append(points,[]int{1,2,3})
points = append(points,[]int{4,5,6})
fmt.Println(points)

而后打印结果

[root@linuxea.com /opt/Golang/work2]# go run dmake.go
[[1 2 3] [4 5 6]]

3 多维查询

仍然使用索引进行查询。对于多维切片来讲,获取其中某一维就需要多次索引。如果要获取2,就需要在1维索引0位置的切片points[0],而后通过索引1位置points[0][2]找到

    fmt.Println(points)
    fmt.Println(points[0])
    fmt.Println(points[0][3])

运行

[root@linuxea.com /opt/Golang/work2]# go run dmake.go
[[1 2 3] [4 5 6]]
[1 2 3]
2

切片与数组的区别

  • 切片

定义一个切片。如下:

slice01 :=  []int{1,2,3}

而后,赋值给slice02

slice02 := slice01

而后在修改slice02索引0位置的元素,并打印

slice02[0] = 99
fmt.Printf("slice01:%v,slice02:%vn",slice01,slice02)

在修改slice01索引0位置的元素,并打印

    slice01[0] = 1
    fmt.Printf("slice01:%v,slice02:%vn",slice01,slice02)

代码块如下:

package main
import "fmt"
func main(){

    slice01 := []int{1,2,3}
    slice02 := slice01

    fmt.Printf("slice01:%v,slice02:%vn",slice01,slice02)

    slice02[0] = 99
    fmt.Printf("slice01:%v,slice02:%vn",slice01,slice02)

    slice01[0] = 1
    fmt.Printf("slice01:%v,slice02:%vn",slice01,slice02)
}

运行

[root@linuxea.com /opt/Golang/work2]# go run dmake2.go
slice01:[1 2 3],slice02:[1 2 3]
slice01:[99 2 3],slice02:[99 2 3]
slice01:[1 2 3],slice02:[1 2 3]

当修改了slice01的时候,slice02也会随着改变,当修改slice02的时候,slice01也会随着改变。

  • 数组

数组是长度固定的,在go中,数组是不可变的,是值类型。

用切片同样的定义和修改数组看会发生什么?

package main
import "fmt"
func main(){

    array01 := [3]int{1,2,3}
    array02 := array01

    fmt.Printf("array01:%v,array02:%vn",array01,array02)

    array02[0] = 99
    fmt.Printf("array01:%v,array02:%vn",array01,array02)

    array01[0] = 1
    fmt.Printf("array01:%v,array02:%vn",array01,array02)
}

运行

[root@linuxea.com /opt/Golang/work2]# go run dmake3.go 
array01:[1 2 3],array02:[1 2 3]
array01:[1 2 3],array02:[99 2 3]
array01:[1 2 3],array02:[99 2 3]

此时的array01修改不会影响到array02,array02也不会影响到array01。

这是为什么?

切片的底层有三个元素,point(指针),len,cap。有一个底层数组,假设这个数组地址是0XZ2S63Q,point就指向0XZ2S63Q。而将slice01赋值给slice02(slice02 := slice01)的时候,是值传递。slice01就相当于被拷

在go中赋值是值传递,相当于一次COPY

贝到slice02,但是地址仍然指向slice01的0XZ2S63Q。如下图

20190914-2.png

这也就是为什么对slice01修改会作用于slice02,slice02修改也会作用于slice01。

而当数组在赋值的时候,会在内存中重新申请一个同样大小底层数组,并将值COPY到赋值的函数上。如下:

20190914-3.png

这也就是为什么数组重新赋值后,修改互相不影响。

相关文章

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

发布评论