数组
快速入门
//定义数组
var hens [6]float64
//遍历、赋值、输出
for i := 0; i < len(hens) ; i++ {
hens[i] = float64(i)
}
内存布局
初始化
//初始化 - 四种方式
var array1 [3]int = [3]int{1,2,3}
var array2 = [3]int{1,2,3}
var array3 = [...]int{1,2,3}
var array4 = [...]int{0:100,1:500,4:999,3:1000}
fmt.Println(array1) [1 2 3]
fmt.Println(array2) [1 2 3]
fmt.Println(array3) [1 2 3]
fmt.Println(array4) [100 500 0 1000 999]
数组遍历
//数组遍历
// 常规方式
for i := 0; i < len(array1); i++ {
fmt.Println(array1[i])
}
// for-range ---- key,value名字自己指定
for key, value := range array1 {
fmt.Println(key,value)
}
for _, value := range array1 {
fmt.Println(value)
}
注意事项
- 数组是多个相同的数据类型的组合,一旦一个数组声明后,其长度是固定的,不能动态变化。
- var arr []int 是一个切片,slice 区别于数组
- 数组创建后,如果没有赋值,有默认值
- 数组默认是值传递,因此进行值拷贝,不会影响作为参数传入的原数组
- 如果想修改原数组,可以使用引用传递(指针)
- 长度是数组的一部分,在传递参数时,必须考虑数组的长度
切片
- 切片英文slice
- 切片是数组的一个引用
- 切片的长度是可以变化的
- 切片的使用方式和数组类似,遍历、访问
切片定义的基本语法 : var a []int
//快速入门
array := [5]int{1,2,3,4,5}
//切片slice引用数组array下标 [1,3)个元素
slice := array[1:3]
fmt.Println(slice) //[2,3]
fmt.Println(len(slice)) //2
fmt.Println(cap(slice)) //4
切片使用方式
//使用方式1 : 定义切片去引用创建好的数组 slice := array[1:3]
arr := [5]int{1,2,3,4,5}
//切片slice引用数组array下标 [1,3)个元素
slice1 := arr[1:3]
fmt.Println(slice1)
//使用方式2 : 通过make创建切片
var slice2 = make([]int,4,10) //切片类型、len、cap
fmt.Println(slice2)
//使用方式3 : 直接指定具体数组
var slice3 = []int{1,3,5}
fmt.Println(slice3)
内存布局
- slice是一个引用类型
- slice可以理解为一种数据结构,
type slice struct{
*ptr
len
cap
}
append
//append
var slice4 = []int{100,200,300}
slice5 := append(slice4,400,500,600) //追加元素
slice6 := append(slice4,slice4...) //追加切片
fmt.Println(slice4,len(slice4),cap(slice4),&slice4[0])
fmt.Println(slice5,len(slice5),cap(slice5),&slice5[0])
fmt.Println(slice6,len(slice6),cap(slice6),&slice6[0])
[100 200 300] 3 3 0xc042010340
[100 200 300 400 500 600] 6 6 0xc04200a390
[100 200 300 100 200 300] 6 6 0xc04200a3c0
- 切片底层append操作的本质是对数组扩容
- go底层会创建一个新的数组newArr(扩容后大小)
- 将slice原来包含的内容拷贝到新的数组newArr
-
copy
//copy
var slice7 = []int{101,202,303}
var slice8 = make([]int,10,10)
fmt.Println(slice7,slice8)
[101 202 303] [0 0 0 0 0 0 0 0 0 0]
copy(slice8,slice7)
fmt.Println(slice7,slice8)
[101 202 303] [101 202 303 0 0 0 0 0 0 0]
fmt.Println(&slice7[0],&slice8[0])
0xc042056120 0xc04208a050
copy(a,b)要求两个参数都是切片
- a、b的数据空间是独立的,互不影响
slice和string
//string 和 slice
str := "helle"
fmt.Println(str) //helle
sliceA := []byte(str)
sliceA[4] = 'o'
str = string(sliceA[0])
fmt.Println(str) //hello
str_2 := "我love你"
fmt.Println(str_2) //我love你
sliceB := []rune(str_2)
sliceB[0] = 'I'
str_2 = string(sliceB)
fmt.Println(str_2) //Ilove你
- string底层是一个byte数组,因此string也可以进行切片处理
- string是不可修改的,不可以通过 str[0]=’z’ 的方式修改字符串
- 如果需要修改字符串,先将string转化为 []byte 或者 []rune =》 修改 =》 重新转换为string
- 转化为 []byte 可以处理英文和数字,但不能处理中文(一个汉字三个字节)
- 转化为 []rune 可以处理英文和数字、以及中文
注意事项