1. 什么是切片
Go 语言切片是对数组的抽象,切片是数组的一个引用,数组是值类型,切片是引用类型,切片的长度是可以变化的,所以切片是一个可以动态变化的数组,可以理解成Java中的ArrayList。
1.1 切片的定义语法
var 切片名称 []类型
示例:var a []int
注意:切面的声明和数组的声明稍微有点区别,切片声明时不知道具体的长度
2. 切片的创建方式
2.1 方式一
定义一个切片,然后让切片去引用一个已经创建好的数组
package main
import "fmt"
func main() {
var arr [5]int = [...]int{1, 2, 3, 4, 5}
// 声明一个切片,然后引用已经定义好的数组
// 引用数组元素的区间是:前闭后开
slice :=arr[1:3]
// [2 3]
fmt.Println(slice)
}
2.2 方式二
利用 make 来创建
func make
func make(Type, size IntegerType) Type
- Type:指定数据类型
- size:指定长度,默认该切片的容量等于其长度。切片支持第二个整数实参可用来指定不同的容量; 它必须不小于其长度,因此 make([]int, 0, 10) 会分配一个长度为0,容量为10的切片。
package main
import "fmt"
func main() {
var sliceArr []int = make([]int, 5)
sliceArr[0] = 1
sliceArr[1] = 2
// [1 2 0 0 0]
fmt.Println(sliceArr)
}
2.3 方式三
定义一个切片,直接就指定具体的数组
package main
import "fmt"
func main() {
var strSlice []string = []string{"A", "B", "C"}
// [A B C]
fmt.Println(strSlice)
}
3. 切片的遍历
for循环遍历for-range遍历
package main
import "fmt"
func main() {
var arrays [5]int = [...]int{1, 2, 3, 4, 5}
// 声明一个切片,然后引用已经定义好的数组
// 引用数组元素的区间是:前闭后开
arr :=arrays[1:4]
for i := 0; i < len(arr); i++ {
fmt.Printf("index=%v, val=%v\n", i, arr[i])
}
fmt.Println(arr)
for i,v := range arr {
fmt.Printf("i=%v, v=%v\n", i, v)
}
}
4. 切片使用细节
- 切片初始化引用数组时,下标不能超过数组的最大长度,即
var slice = [0 ~ len(array)],几种特殊情况的简写
var slice = arr[0:end] 简写为 var slice = arr[:end]
var slice = arr[start:len(arr)] 简写为 var slice = arr[start:]
var slice = arr[0:len(arr)] 简写为 var slice = arr[:]
-
内置函数
cap、append和copy函数的使用
(1) func cap(v Type) int :返回切片中元素的数量
(2) func append(slice []Type, elems ...Type) []Type :在切片中动态添加元素
package main
import "fmt"
func main() {
var slice3 []int = []int{100, 200, 300}
slice3 = append(slice3, 400, 500)
// [100 200 300 400 500]
fmt.Println(slice3)
var arr3 []int = []int{600, 700}
// [100 200 300 400 500 600 700],相当于 Java 中 ArrayList 的 addAll 方法
slice3 = append(slice3, arr3...)
fmt.Println(slice3)
var keys []int
var arr6 [3]int = [3]int {1, 2, 3}
for _,v := range arr6 {
keys = append(keys, v)
}
// [1 2 3]
fmt.Println(keys)
}
append 的本质是对数组进行扩容,将切片 slice3 指向扩容后的数组而已。
(3) func copy(dst, src []Type) int :对切片进行拷贝,会把 src 中数据复制到 dst 中,复制后的数是独立内存空间,互不影响。
package main
import "fmt"
func main() {
var src []int = []int{1, 2, 3}
var dst = make([]int, 1)
copy(dst, src)
// dst=[1], src=[1 2 3]
fmt.Printf("dst=%v, src=%v\n",dst, src)
}
5. 字符串和切片
string底层是一个byte数组,所以 string 也可以用切片进行处理
package main
import "fmt"
func main() {
str := "abcde@AAAAA"
slice := str[6:]
// slice= AAAAA
fmt.Println("slice=", slice)
}
- 字符串被初始化后不能被修改,如果要修改,可以采用如下方式
package main
import "fmt"
func main() {
str := "abced@AAAAA"
var b []rune = []rune(str)
// b= [97 98 99 101 100 64 65 65 65 65 65]
fmt.Println("b=", b)
b[0] = 'A'
str = string(b)
// str= Abced@AAAAA
fmt.Println("str=", str)
}
注意:这里推荐使用 []rune,因为 []byte无法处理中文