数组
-
Go 编译器需要在编译阶段就知道数组类型的长度
-
如果两个数组类型的元素类型 T 与数组长度 N 都是一样的,那么这两个数组类型是等价的,如果有一个属性不同,它们就是两个不同的数组类型。
-
数组类型不仅是逻辑上的连续序列,而且在实际内存分配时也占据着一整块内存
-
预定义函数 len 可以用于获取一个数组类型变量的长度,通过 unsafe 包提供的 Sizeof 函数,我们可以获得一个数组变量的总大小(字节)
-
数组声明
func TestArrayIni(t *testing.T) { var arr1 [2]int64 // 声明并初始化为默认零值 arr1[0] = 1 // 赋值 arr2 := [3]int{1, 2, 3} // 声明同时初始化 arr3 := [...]string{"a", "b", "c", "d"} arr4 := [2][2]int{{1, 2}, {3, 4}} // 多维数组初始化 t.Log(arr1, arr2, arr3, arr4) // [1 0] [1 2 3] [a b c d] [[1 2] [3 4]] } -
数组遍历:a[开始索引(包含), 结束索引(不包含)]
func TestArrayTravel(t *testing.T) { a := [...]string{"a", "b", "c", "d"} for idx, elem := range a { t.Log(idx, elem) } for _, elem := range a { t.Log(elem) } } -
数组截取
func Test_slit(t *testing.T) { a := [...]int{1, 2, 3, 4, 5} a1 := a[1:2] // [2] a2 := a[1:3] // [2,3] a3 := a[2:] // [3,4,5] a4 := a[:3] // [1,2,3] fmt.Println( a1, a2, a3, a4, ) }
切片
-
切片声明仅仅是少了一个“长度”属性
type slice struct { array unsafe.Pointer //是指向底层数组的指针; len int //是切片的长度,即切片中当前元素的个数; cap int //是底层数组的长度,也是切片的最大容量,cap 值永远大于等于 len 值。 } -
可以说,切片之于数组就像是文件描述符之于文件。
-
针对元素是 int 型的数组,新数组的容量是当前数组的 2 倍
-
切片内部结构:
```
func TestSliceInit(t *testing.T) {
s0 := []int{}
for i := 0; i < 10; i++ {
s0 = append(s0, i)
t.Log(len(s0), cap(s0))
} // 10 16
s1 := []int{}
s2 := []int{1, 2, 3}
t.Log(s1, len(s1), cap(s1)) // [] 0 0
t.Log(s2, len(s2), cap(s2)) // [1 2 3] 3 3
}
```
-
切片共享存储结构
数组 vs. 切⽚
- 容量是否可伸缩
- 是否可以进⾏⽐较:数组可以比较,切片不可以
func TestSliceCompare(t *testing.T) {
s1 := []int{1, 2, 3}
s2 := []int{1, 2, 3}
t.Log(s1 == s2)
}
// invalid operation: s1 == s2 (slice can only be compared to nil)