一、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]
数组和切片的区别
切片
引用(地址相同)
函数中 -- 修改值会影响外部函数
数据拷贝 -- 拷贝引用
相同唯一类型
长度不固定
数组
相同唯一类型
长度固定
连续的数据