05、GO数组与切片

 一、Go语言的数组

Go 语⾔提供了数组类型的数据结构。
数组是具有相同唯⼀类型的⼀组已编号且⻓度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者⾃定义类型。
数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第⼀个元素索引为 0,第⼆个索引为 1,以此类推。

 示例:定义一个数组:

package main

import "fmt"

func main() {
	var arr1 [5] int
	fmt.Println("vim-go")
	fmt.Println(arr1)
}

执行结果

在go语言里面如果定义一个变量没有赋值会自动生成一个初始值,数组的初始值为0

[root@localhost src]# go run example7.go 
vim-go
[0 0 0 0 0]

两种定义变量的区别

用 var 定义变量可以不用赋初始值

使用  a := 的方法定义必须有初始值

示例:定义数组,给数组赋值

package main

import "fmt"

func main() {
	var arr1 [5] int
	fmt.Println("vim-go")
	fmt.Println(arr1)
	arr2 := [5]int{0,1,2,3,4}
	fmt.Println(arr2)
	arr2[0]=100
	arr2[1]=555
	arr2[4]=99
	fmt.Println(arr2)
}

示例:使用for循环获取数组的值

package main

import "fmt"

func main() {
	var arr1 [5] int
	fmt.Println("vim-go")
	for i:=0;i<len(arr1);i++ {
	arr1[i] = i
	}
	fmt.Println(arr1)
}

执行结果

[root@localhost src]# go run for.go 
vim-go
[0 1 2 3 4]

数组的遍历

示例:使用range遍历数组

package main

import "fmt"

func main() {
	arr2 := [5]int{0,1,2,3,4}
	arr2[0]=100
	arr2[1]=555
	arr2[4]=99
	fmt.Println(arr2)
	
	// 下标,值
	for i,item := range arr2{
		fmt.Println(i,item)
	}
}
[root@localhost src]# go run example7.go 
[100 555 2 3 99]
0 100
1 555
2 2
3 3
4 99

示例:遍历但是只取 item值

可以使用下划线 _ 来定义一个不输出的变量

package main

import "fmt"

func main() {
	//var arr1 [5] int
	//fmt.Println("vim-go")
	//fmt.Println(arr1)
	arr2 := [5]int{0,1,2,3,4}
	//fmt.Println(arr2)
	arr2[0]=100
	arr2[1]=555
	arr2[4]=99
	fmt.Println(arr2)
	
	// 下标,值
	for i,item := range arr2{
		fmt.Println(i,item)
	}
	// 如何遍历但是只取item?
	for _,item := range arr2{
		fmt.Println(item)
	}
}
[root@localhost src]# go run example7.go 
[100 555 2 3 99]
0 100
1 555
2 2
3 3
4 99
100
555
2
3
99

 定义二维数组

	var arr3 [2][3] int
	arr3[0][1] = 100
	fmt.Println(arr3)
[[0 100 0] [0 0 0]]

2. Go 语⾔切⽚(Slice)

什么是切片 

Go 语⾔切⽚是对数组的抽象。
Go 数组的⻓度不可改变,在特定场景中这样的集合就不太适⽤,Go 中提供了⼀种灵活,功能强悍的内置类型切⽚
("动态数组"),与数组相⽐切⽚的 ⻓度是不固定 的,可以追加元素,在追加时可能使切⽚的容量增⼤

示例:切片的定义

package main

import "fmt"

func main() {
	arr2 :=[5]int{100,500,2,3,99}
	var slice1 []int
	fmt.Println(slice1)
	var slice2 []int = make([]int,5)
	fmt.Println(slice2)
	slice3 := make([]int, 5)
	fmt.Println(slice3)
	
	// 通过对数组进行切片,初始化数据
	slice4 := arr2[0:2]
	fmt.Println(slice4)
	slice5 := slice4
	fmt.Println(slice5)
	slice6 := arr2
	fmt.Println(slice6)
}
[root@localhost src]# go run slice.go 
[]
[0 0 0 0 0]
[0 0 0 0 0]
[100 500]
[100 500]
[100 500 2 3 99]
2.3 len() cap() 函数
切⽚是可索引的,并且可以由 len() ⽅法获取⻓度。
切⽚提供了计算容量的⽅法 cap() 可以测量切⽚最⻓可以达到多少。
以下为具体实例:
import "fmt"

func main() {
	arr2 :=[5]int{100,500,2,3,99}
	var slice1 []int
	fmt.Println(slice1)
	var slice2 []int = make([]int,5)
	fmt.Println(slice2)
	slice3 := make([]int, 5)
	fmt.Println(slice3)
	
	// 通过对数组进行切片,初始化数据
	slice4 := arr2[0:2]
	fmt.Println(slice4)
	slice5 := slice4
	fmt.Println(slice5)
	slice6 := arr2
	fmt.Println(slice6)
	fmt.Println("**************************")
	//len cap
	fmt.Println(len(slice3),cap(slice3))
	fmt.Println(len(arr2),cap(arr2))
	

}
[root@localhost src]# go run slice.go 
[]
[0 0 0 0 0]
[0 0 0 0 0]
[100 500]
[100 500]
[100 500 2 3 99]
**************************
5 5
5 5
如果想增加切⽚的容量,我们必须创建⼀个新的更⼤的切⽚并把原分⽚的内容都拷⻉过来。
下⾯的代码描述了从拷⻉切⽚的 copy ⽅法和向切⽚追加新元素的 append ⽅法。

 示例:使用append方法添加新元素,slice4里面原本只有两个元素,新增两个数600,700

package main

import "fmt"

func main() {
	arr2 :=[5]int{100,500,2,3,99}
	var slice1 []int
	fmt.Println(slice1)
	var slice2 []int = make([]int,5)
	fmt.Println(slice2)
	slice3 := make([]int, 5)
	fmt.Println(slice3)
	
	// 通过对数组进行切片,初始化数据
	slice4 := arr2[0:2]
	fmt.Println(slice4)
	slice5 := slice4
	fmt.Println(slice5)
	slice6 := arr2
	fmt.Println(slice6)
	fmt.Println("**************************")
	//len cap
	fmt.Println(len(slice3),cap(slice3))
	fmt.Println(len(arr2),cap(arr2))
	
	// append
	slice4 = append(slice4,600,700)
	fmt.Println(slice4)


}
[root@localhost src]# go run slice.go 
[]
[0 0 0 0 0]
[0 0 0 0 0]
[100 500]
[100 500]
[100 500 2 3 99]
**************************
5 5
5 5
[100 500 600 700]
3. 数组与切⽚
3.1 数组的容量和⻓度
数组的容量和⻓度是⼀样的。cap() 函数和 len() 函数均输出数组的容量(即⻓度)
3.2 类型
数组是 值类型 ,将⼀个数组赋值给另⼀个数组时,传递的是⼀份拷⻉。
切⽚是 引⽤类型 ,切⽚包装的数组称为该切⽚的底层数组。看下⾯的例⼦:
//a是⼀个数组,注意数组是⼀个固定⻓度的,初始化时候必须要指定⻓度,不指定⻓度的话就是切⽚了
a := [3]int{1, 2, 3}
//b是数组,是a的⼀份拷⻉
b := a
//c是切⽚,是引⽤类型,底层数组是a
c := a[:]
for i := 0; i < len(a); i++ {
 a[i] = a[i] + 1
}
//改变a的值后,b是a的拷⻉,b不变,c是引⽤,c的值改变
fmt.Println(a) //[2,3,4]
fmt.Println(b) //[1 2 3]
fmt.Println(c) //[2,3,4]

 数组拷贝和切片拷贝

	// 数组的拷贝
	arr4 := [3]int{1,2,3}
	arr5 := arr4
	fmt.Println(arr4, arr5)
	fmt.Println(&arr4[0], &arr5[0])
	
	//切片的拷贝
	//没有指定长度就是切片
	slice7 := []int{1,2,3}
	slice8 := slice7
	fmt.Println(slice7,slice8)
	fmt.Println(&slice7[0],&slice8[0])
	
	arr4[0] = 100
	slice7[0] = 100
	fmt.Println(arr4,slice7)
[1 2 3] [1 2 3]
0xc0000140f0 0xc000014108
[1 2 3] [1 2 3]
0xc000014150 0xc000014150
[100 2 3] [100 2 3]

数组和切片的区别

切片

        引用(地址相同)

        函数中 -- 修改值会影响外部函数

        数据拷贝  -- 拷贝引用

        相同唯一类型

        长度不固定

数组

        相同唯一类型

        长度固定

        连续的数据

        

猜你喜欢

转载自blog.csdn.net/qq_48391148/article/details/126189868
今日推荐