数组和切片
数组Array:
- 数组的数据类型是值类型
- 数组声明时需要指定长度。[size]type{}
- 数组是固定长度,不可以扩容
- 数组获取len()、cap()的值是一样的。因为数组是固定长度,长度和容量一致
切片Slice:
- 切片的数据类型是引用类型
- 切片声明时不需要指定长度。[]type{};但是make关键字声明时可以指定切片的长度和容量make([]type, len, size)
- 切片是不定长,可以扩容。切片也被称为变长数组、动态数组
- 切片获取len()、cap()的值不一定一样。因为切片不定长,但是容量可以自动扩容
- 切片其实是指向一个底层数组,操作切片的元素实际是操作数组的元素。如果切片发生扩容,会新建底层数组。
数组的声明
var a [3]int //声明并初始化为默认零值
a[0] = 1
b := [3]int{
1, 2, 3} //声明同时初始化
c := [2][2]int{
{
1, 2}, {
3, 4}} //多维数组初始化
数组元素遍历
与其他主要编程语言的差异
func TestTravelArray(t *testing.T) {
a := [...]int{
1, 2, 3, 4, 5} //不指定元素个数
for idx/*索引*/, elem/*元素*/ := range a {
fmt.Println(idx, elem)
}
}
package array_test
import "testing"
func TestArrayInit(t *testing.T) {
//声明并初始化为默认零值
var arr [3]int
//声明同时初始化
arr1 := [4]int{
1, 2, 3, 4}
arr3 := [...]int{
1, 2, 3, 4, 5} // 不用写数组个数, ... 自动处理
arr1[1] = 5
t.Log(arr[1], arr[2])
t.Log(arr1, arr3)
}
// go语言遍历
func TestArrayTravel(t *testing.T) {
arr3 := [...]int{
1, 2, 3, 4, 5}
for i := 0; i < len(arr3); i++ {
t.Log(arr3[i])
}
// idx: 索引 e:元素值
for idx, e := range arr3 {
t.Log(idx, e)
}
// go语言是个有严格约束的语言,声明或者取了某个值,不用的话编译过不了
//for idx,e := range arr3{
// t.Log(e)
//}
// go语言中"_"下划线代表我们并不关心它的结果,但是有一个返回值占位
for _, e := range arr3 {
t.Log(e)
}
}
// 数组截取
func TestArraySection(t *testing.T) {
arr3 := [...]int{
1, 2, 3, 4, 5}
arr3_sec := arr3[:] // 从头部到尾部截取
t.Log(arr3_sec)
}
数组截取
a[开始索引(包含), 结束索引(不包含)]
a := [...]int{
1, 2, 3, 4, 5}
a[1:2] //2
a[1:3] //2,3
a[1:len(a)] //2,3,4,5
a[1:] //2,3,4,5
a[:3] //1,2,3
切片内部结构
切片声明
var s0 []int
s0 = append(s0, 1)
s := []int{
}
s1 := []int{
1, 2, 3}
s2 := make([]int, 2, 4)
/*[]type, len, cap
其中len个元素会被初始化为默认零值,未初始化元素不不可以访问
*/
切片共享存储结构
package slice_test
import "testing"
/*
var s0 []int
s0 append(s0,1)
s:=[]int{}
s1:=[]int1,2,3}
s2:=make([]int,2,4)
[]type,len,cap
其中len个元素会被初始化为默认零值,未初始化元素不可以访问
*/
func TestSliceInit(t *testing.T) {
var s0 []int
t.Log(len(s0), cap(s0))
s0 = append(s0, 1)
t.Log(len(s0), cap(s0))
s1 := []int{
1, 2, 3, 4}
t.Log(len(s1), cap(s1))
s2 := make([]int, 3, 5)
t.Log(len(s2), cap(s2))
//t.Log(s2[0], s2[1], s2[2], s2[3], s2[4]) // runtime error: index out of range [3] with length 3 [recovered]
s2 = append(s2, 1)
t.Log(s2[0], s2[1], s2[2], s2[3])
t.Log(len(s2), cap(s2))
}
// 数组增长 , 可类比java中ArrayList,数组扩容
func TestSliceGrowing(t *testing.T) {
s := []int{
}
for i := 0; i < 10; i++ {
s = append(s, i)
t.Log(len(s), cap(s))
}
}
func TestSliceShareMemory(t *testing.T) {
year := []string{
"January", "February", "March", "April", "May", "June", "July", "August", "September",
"October", "November", "December"}
Q2 := year[3:6]
t.Log(Q2, len(Q2), cap(Q2))
summer := year[5:8]
t.Log(summer, len(summer), cap(summer))
summer[0] = "Unknown"
t.Log(Q2)
t.Log(year)
}
func TestSliceCompare(t *testing.T) {
//a := []int{1, 2, 3}
//b := []int{1, 2, 3}
//if a == b {
// t.Log("true") // 切片不能比较 .\slice_test.go:53:5: invalid operation: a == b (slice can only be compared to nil)
//}
}
PS:学习笔记,侵删!