3.9 数组对比切片有哪些优势?¶
1. 编译检查越界¶
由于数组在声明后,长度就是固定的,因此在编译的时候编译器可以检查在索引取值的时候,是否有越界
func main() {
array := [2]int{}
array[2] = 2 //invalid array index 2 (out of bounds for 2-element array)
}
而切片的长度只有运行时才能知晓,编译器无法检查。
2. 长度是类型的一部分¶
在声明一个数组的类型时,需要指明两点:元素的类型和元素的个数。
var array [2]int
因此长度是数组类型的一部分,两个元素类型相同,但可包含的元素个数不同的数组,属于两个类型。
func main() {
var array1 [2]int
var array2 [2]int
var array3 [3]int
fmt.Println(reflect.TypeOf(array1) == reflect.TypeOf(array2)) // true
fmt.Println(reflect.TypeOf(array1) == reflect.TypeOf(array3)) // false
}
基于这个特点,可以用它来达到一些合法性校验的目的,例如 IPv4 的地址可以声明为 [4]byte,符合该类型的数组就是合法的 ip,反之则不合法。
3. 数组可以比较¶
类型相同的两个数组可以进行比较
func main() {
array1 := [2]int{1,2}
array2 := [2]int{1,2}
array3 := [2]int{2,1}
fmt.Println(array1 == array2) // true
fmt.Println(array1 == array3) // false
}
类型不同(长度不同)的数组 和 切片均不行。
可比较这一特性,决定了数组也可以用来当 map 的 key 使用。
func main() {
array1 := [2]int{1,2}
dict := make(map[[2]int]string)
dict[array1] = "hello"
fmt.Println(dict) // map[[1 2]:hello]
}