目录
一、数组
1、数组的声明
package array
import "testing"
//数组初始化
func TestArrayInit(t *testing.T) {
//声明并初始化默认值为0
var a [3]int
//声明同事初初始化一维数组
b := [3]int{1, 2, 3}
//声明同时初始化二维数组
c := [2][2]int{{1, 2}, {3, 4}}
//不指定数组长度,用三个点代替,go会自动帮我们初始化到对应的长度
d := [...]int{1,2,3,4,5}
t.Log(a[0], b[1], c[0][1], d[0])
}
2、循环数组
package array
import "testing"
//循环数组
func TestArrayTravel(t *testing.T) {
var arr = [3]int{1, 2, 3}
//使用 for 循环数组(不推荐)
for i := 0; i < len(arr); i++ {
t.Log(arr[i])
}
//使用 range 关键字循环数组(推荐),类似于php里面的 foreach
for idx, v := range arr {
t.Log(idx, v)
}
//如果不想用 idx ,可以使用 '_' 做缺省值。不能不写
for _, v := range arr {
t.Log(v)
}
}
//循环二维数组
func Test2DimensionalArrayTravel(t *testing.T) {
var arr = [2][2]int{{1, 2}, {3, 4}}
for _, val := range arr {
for k, v := range val {
t.Log(k, v)
}
}
}
3、数组截取
a[开始索引(包含),结束索引(不包含)]
package array
import "testing"
//数组截取
func TestArraySection(t *testing.T){
arr := [...]int{0, 1, 2, 3, 4}
//截取数组,从 arr[1] 开始到 arr[2]结束 ,但不包含 arr[2]
t.Log(arr[1:2]) //[1]
//截取数组,从 arr[1] 开始到 arr[3]结束 ,但不包含 arr[3]
t.Log(arr[1:3]) //[1 2]
//截取数组,从 arr[1] 开始到数组的结尾
t.Log(arr[1:len(arr)]) //[1 2 3 4]
//截取数组,从 arr[1] 开始到数组的结尾另一种写法
t.Log(arr[1:]) //[1 2 3 4]
//截取数组,从数组的第一个元素开始到 arr[3] ,但不包含 arr[3]
t.Log(arr[:3]) //[0 1 2]
}
二、切片
1、切片的内部结构
也是一个连续的数据存储结构,用起来的感觉像一个可变长的数组,但是如果从内部分析,它和数组还是不一样,它的结构如下:
2、声明切片
package slice
import "testing"
//声明切片
func TestSliceStatement(t *testing.T){
//用 var 声明一个切片,后面不要加 {}
var s0 []int
//查看切片长度和容量的变化
t.Log(len(s0), cap(s0)) //0, 0
//如果需要往切片追加元素,用 append() 函数
s0 = append(s0, 1)
t.Log(len(s0), cap(s0)) //1, 1
//用 := 推导的方式声明一个切片,后面需要加 {}, 初始值为 0
s1 := []int{}
t.Log(len(s1), cap(s1)) //0, 0
//声明一个切片并赋初值
s2 := []int{1, 2, 3, 4}
t.Log(len(s2), cap(s2)) //4, 4
//用 make() 函数来定义一个切片(推荐)
//在 Go 语言中创建某一种类型的变量,我们经常会用到 make()
s3 := make([]int, 3, 5)
//此处我们发现切片的长度和容量是不一样的
t.Log(len(s3), cap(s3)) //3, 5
}
package slice
import "testing"
//切片初始化
func TestSliceInit(t *testing.T) {
//这里我们将切片的长度和容量设置为不一样长。
s3 := make([]int, 3, 5)
t.Log(len(s3), cap(s3)) //3, 5
//因为我们长度定义的长度为 3,Go 就只给我们初始化了 3 个值,如果想访问第四个元素就会报错
t.Log(s3[0], s3[1], s3[2], s3[3]) //index out of range [3] with length 3
}
package slice
import "testing"
//切片初始化
func TestSliceInit(t *testing.T) {
//这里我们将切片的长度和容量设置为不一样长。
s3 := make([]int, 3, 5)
t.Log(len(s3), cap(s3)) //3, 5
s3 = append(s3, 3)
t.Log(len(s3), cap(s3)) //4, 5
t.Log(s3[3]) // 1
}
3、切片的可变长原理
package slice
import "testing"
//切片长度的变化情况
func TestSliceGrowing(t *testing.T){
s :=[]int{}
for i :=0; i < 10; i++ {
s = append(s, i)
t.Log(len(s,), cap(s))
}
}
结论:切片的增长规律为,当切片的长度增大到容量的最大值时,切片的容量会两倍的增加。
这样解释了为什么 append() 函数需要写成 s = append(s, 1),而不是 append(s, 1) 了,因为当切片的存储空间变大后,是重新获取了一块儿连续的存储空间,故需要重新赋值。
4、切片共享存储结构
package slice
import "testing"
//切片存储空间是共享的
func TestShareMenory(t *testing.T){
year := []string{"Jay", "Feb", "Mar", "Apr", "May", "Jun", "Juy", "Aug", "Sep", "Oct", "Nov", "Dec"}
//获取 Q2 季度的月份
Q2 := year[3:6]
t.Log(len(Q2), cap(Q2)) //3, 9
t.Log(Q2) //[Apr May Jun]
//获取夏天的月份
summer := year[5:8]
t.Log(len(summer), cap(summer)) //3, 7
t.Log(summer) //[Jun Juy Aug]
//将 summer 切片中的的第一个元素改成 Unknown
summer[0] = "Unknown"
//我们会发现 Q2 切片中的元素也被修改了
t.Log(Q2) //[Apr May Unknown]
}
结论:切片的存储空间是共享的。
5、切片是否可以进行比较
package slice
import "testing"
//切片是否可进行比较
func TestSliceComparing(t *testing.T) {
s1 := []int{1, 2, 3, 4}
s2 := []int{1, 2, 3, 4}
//这里会报错 slice can only be compared to nil
if s1 == s2 {
t.Log("yes")
} else {
t.Log("no")
}
}
结论:切片之间不能进行比较。
三、数组和切片的异同
- 数组容量是固定的,切片的容量可伸缩。
- 数组间是可进行比较的,而切片不行。
注:这篇博文是我学习中的总结,如有转载请注明出处:https://blog.csdn.net/DaiChuanrong/article/details/117767982
上一篇:Go循环、判断和switch
下一篇:Go数据类型