go同构符合类型:定长数组和变长切片

数组

go数组的两个属性:

长度固定

同构元素组成

声明

var arr [N]T

Go 编译器需要在编译阶段就知道数组类型的长度,所以,我们只能用整型数字面值或常量表达式作为 N 值。

如果两个数组类型的元素类型 T 与数组长度 N 都是一样的,那么这两个数组类型是等价的,如果有一个属性不同,它们就是两个不同的数组类型。

func foo(arr [5]int) {}
func main() {
    var arr1 [5]int
    var arr2 [6]int
    var arr3 [5]string

    foo(arr1) // ok
    foo(arr2) // 错误:[6]int与函数foo参数的类型[5]int不是同一数组类型
    foo(arr3) // 错误:[5]string与函数foo参数的类型[5]int不是同一数组类型
}  

数组类型不仅是逻辑上的连续序列,而且在实际内存分配时也占据着一整块内存。Go 编译器在为数组类型的变量实际分配内存时,会为 Go 数组分配一整块、可以容纳它所有元素的连续内存,如下图所示:

 

 

定义

未显式初始化

不进行显式初始化,那么数组中的元素值就是它类型的零值

var arr1 [6]int // [0 0 0 0 0 0]

显式初始化

var arr2 = [6]int {
    11, 12, 13, 14, 15, 16,
} // [11 12 13 14 15 16]

var arr3 = [...]int { 
    21, 22, 23,
} // [21 22 23]
fmt.Printf("%T\n", arr3) // 也可以忽略掉右值初始化表达式中数组类型的长度,用“…”替代,Go 编译器会根据数组元素的个数,自动计算出数组长度

使用下标进行初始化

var arr4 = [...]int{
    99: 39, // 将第100个元素(下标值为99)的值赋值为39,其余元素值均为0
}
fmt.Printf("%T\n", arr4) // [100]int

如果下标值超出数组长度范畴,或者是负数,那么 Go 编译器会给出错误提示,防止访问溢出。

多维数组

var mArr [2][3][4]int

总结

数组类型变量是一个整体,这就意味着一个数组变量表示的是整个数组。无论是参与迭代,还是作为实际参数传给一个函数 / 方法,Go 传递数组的方式都是纯粹的值拷。

 


 

切片

解决数组的两个不足点:

1.固定的元素个数

2.传值机制下导致的开销较大

声明

var nums = []int{1, 2, 3, 4, 5, 6}

切片有自己的长度,只不过这个长度不是固定的,而是随着切片中元素个数的变化而变化的

添加元素append

nums = append(nums, 7) // 切片变为[1 2 3 4 5 6 7
fmt.Println(len(nums)) // 7

 

posted on 2022-07-27 23:30  爱吃柠檬不加糖  阅读(160)  评论(0编辑  收藏  举报

导航