数组
基础知识
数组是一种由固定长度的特定类型元素组成的序列,元素可以是任何数据类型,但是数组中的元素类型必须全部相同。
数组的长度在创建时就已经确定,且不可更改。
数组的下标从0开始。
数组可以使用for循环进行遍历,也可以使用range关键字进行遍历。
数组可以作为参数传递给函数,但是因为数组的长度是固定的,因此数组的长度也需要作为参数传递。
声明并初始化一个数组
var arr [5]int // 定义一个长度为 5 的 int 类型数组 arr[0] = 1 // 给数组中的第一个元素赋值为 1 fmt.Println(arr) // [1 0 0 0 0] arr2 := [3]string{"hello", "world", "go"} // 定义一个长度为 3 的 string 类型数组并初始化 fmt.Println(arr2) // [hello world go]
遍历一个数组
arr := [5]int{1, 2, 3, 4, 5} // 定义一个长度为 5 的 int 类型数组并初始化 // 使用 for 循环遍历数组 for i := 0; i < len(arr); i++ { fmt.Println(arr[i]) } // 使用 for range 遍历数组 for index, value := range arr { fmt.Println(index, value) }
切片
基础知识
- 切片是一种动态数组,它不需要指定长度,在需要的时候可以动态地进行扩容和缩容。
- 切片是一个引用类型,它底层的数据结构是一个数组。
- 切片的长度可以通过len()函数获取,容量可以通过cap()函数获取。
- 切片可以使用make()函数来创建,也可以通过对已有的数组或切片进行切片操作得到。
- 切片的切片操作s[i:j],其中i表示切片的起始位置,j表示切片的结束位置(不包含j位置的元素),可以得到一个新的切片。
- 切片可以使用append()函数向末尾添加元素,当容量不足时会自动进行扩容。
- 切片可以使用copy()函数复制一个切片。
声明并初始化一个切片
// 声明一个空的 int 类型切片 var slice1 []int // 声明并初始化一个 int 类型切片 slice2 := []int{1, 2, 3, 4, 5} // 使用 make 函数创建一个指定长度和容量的 int 类型切片 slice3 := make([]int, 5, 10) // 长度为 5,容量为 10
向切片中添加元素
// 使用 append 函数向切片中添加元素 slice1 := []int{1, 2, 3} slice1 = append(slice1, 4, 5, 6) // 添加多个元素 fmt.Println(slice1) // [1 2 3 4 5 6] // 使用 append 函数将两个切片合并 slice2 := []int{7, 8, 9} slice1 = append(slice1, slice2...) // 将 slice2 中的元素打散后添加到 slice1 中 fmt.Println(slice1) // [1 2 3 4 5 6 7 8 9]
切片的遍历和切片表达式
// 遍历切片 slice := []string{"hello", "world", "go"} for i := 0; i < len(slice); i++ { fmt.Println(slice[i]) } // 切片表达式 arr := [5]int{1, 2, 3, 4, 5} slice := arr[1:3] // slice 的值为 [2 3],包含 arr[1] 和 arr[2] fmt.Println(slice) slice2 := arr[:3] // slice2 的值为 [1 2 3],包含 arr[0]、arr[1] 和 arr[2] fmt.Println(slice2) slice3 := arr[3:] // slice3 的值为 [4 5],包含 arr[3] 和 arr[4] fmt.Println(slice3)
数组和切片的区别
(1)数组的长度固定,切片的长度是动态的。
(2)数组是值类型,将一个数组赋值给另一个数组时,会将所有的元素进行复制;切片是引用类型,将一个切片赋值给另一个切片时,它们将共享底层数组。
(3)数组可以使用==运算符进行比较,切片不能使用==运算符进行比较。
(4)数组可以作为参数传递给函数,但是因为数组的长度是固定的,因此数组的长度也需要作为参数传递;切片可以直接作为参数传递给函数,不需要指定长度。