定长数组与切片
基础
创建
定长
阳性
//先声明,再初始化
var arr [10]T
arr = [10]int{1, 2, 3, 4, 5, 6}
var arr1 = [6]int{1, 2, 3, 4, 5, 6}
arr2 := [6]int{1, 2, 3, 4, 5, 6}
阴性
N := 100
var arr4 [N]int
Invalid array bound 'N', must be a constant expression.
var arr[10]int
arr = [5]int{1, 2, 3, 4, 5}
相同类型的才能赋值.
[10]int 和 [5]int不是相同类型,go语言不存在定长数组的隐式转换。
var arr[10]T
arr = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
超长
变长
arr := []{1, 2, 3, 4, 5, 6}
fmt.Println(arr)
fmt.Printf("arr [length:%d] [size: %d]\n", len(arr), unsafe.Sizeof(arr))
//结果
[1 2 3 4 5 6]
arr [length:6] [size: 24]
注意点
默认最小的构造容量为24,本例的初始化的长度则为6。
猜想(详细可见C++版本的对应猜想实现)
一个动态的数组在底层是线上,默认的构造设置capacity为24,长度设置为0,在初始化后,根据实际的定长数组[1, 2, 3, 4, 5, 6]作为参数,设置到当前数组中,对应的SetArray函数(C++):
template<typename T, size_t N>
void SetArray(U (&array)[N]) {
//N为lengh
}
append函数
赋值给本身
arr := []int{1, 2, 3, 4, 5, 6}
fmt.Printf("arr [addr: %p] [length:%d] [size: %d]\n",
&arr,
len(arr),
unsafe.Sizeof(arr))
arr = append(arr, 7)
fmt.Printf("arr [addr: %p] [length:%d] [size: %d]\n",
&arr,
len(arr),
unsafe.Sizeof(arr))
结果:
arr [addr: 0x1400000c030] [length:6] [size: 24]
arr [addr: 0x1400000c030] [length:7] [size: 24]
并没有发生拷贝行为,直接在后面添加
赋值给其他
arr := []int{1, 2, 3, 4, 5, 6}
arr2 := append(arr, 7)
fmt.Printf("arr [addr: %p] [length:%d] [size: %d]\n",
&arr,
len(arr),
unsafe.Sizeof(arr))
fmt.Printf("arr2 [addr: %p] [length:%d] [size: %d]\n",
&arr2,
len(arr2),
unsafe.Sizeof(arr2))