1、切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。
2、 切片的长度可以改变,因此,切片是一个可变的数组。
3、切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。
4、cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array), cap = len(array)其中array是slice引用的数组。
5、切片的定义:var 变量名 []类型。
6、如果 slice == nil,那么 len、cap 结果都等于 0。
7、读写操作实际目标是底层数组,只需注意索引号的差别。
1、直接声明切片
var s []int
2、make方式
var s []int = make([]int, len, cap) //len 长度 cap 容量
3、初始化赋值
var s []int = []int{1, 2, 3}
4、从数组中切片赋值
arr := [5]int{1, 2, 3, 4, 5}
var s []int = arr[2:4]
注意: 在函数内等号左半部分可以用短变量声明s:=来简化程序输写。
| 操作 | 含义 |
|---|---|
s[n] | 切片s中索引为n的位置的项 |
s[:] | 从切片的索引为0到len(s)-1的位置的项 |
s[low:] | 从切片的索引为low到len(s)-1的位置的项 |
s[:hight] | 从切片的索引为0到hight-1的位置的项 |
s[low:hight] | 从切片的索引为low到hight-1的位置的项 |
s[low:hight:max] | 从切片的索引为low到hight-1的位置的项,len=hight-low cap=max-low |
len(s) | 切片s的长度,len(s)<=cap(s) |
cap(s) | 切片s的容量,len(s)<=cap(s) |
1、切片追加另外一个切片
var a = []int{1, 2, 3}
var b = []int{4, 5, 6}
c := append(a, b...)
2、切片追加一个元素
var a = []int{1, 2, 3}
a = append(a, 7)
3、切片追加多个元素
var a = []int{1, 2, 3}
a = append(a, 7, 8, 9)
例:
package main
import (
"fmt"
)
func main() {
data := [...]int{0, 1, 2, 3, 4, 10: 0}
s := data[:2:3]
s = append(s, 100, 200) // 一次 append 两个值,超出 s.cap 限制。
fmt.Println(s, data) // 重新分配底层数组,与原数组无关。
fmt.Println(&s[0], &data[0]) // 比对底层数组起始指针。
}
结果:
[0 1 100 200] [0 1 2 3 4 0 0 0 0 0 0]
0xc00000e3c0 0xc00001a0c0
分析: 在大批量添加数据时,建议一次性分配足够大的空间,以减少内存分配和数据复制开销。
语法:
copy(dst, src []Type) int
例:
package main
import (
"fmt"
)
func main() {
s1 := []int{1, 2, 3, 4, 5}
fmt.Printf("slice s1 : %v\n", s1)
s2 := make([]int, 10)
fmt.Printf("slice s2 : %v\n", s2)
copy(s2, s1)
fmt.Printf("copied slice s1 : %v\n", s1)
fmt.Printf("copied slice s2 : %v\n", s2)
}
结果:
slice s1 : [1 2 3 4 5]
slice s2 : [0 0 0 0 0 0 0 0 0 0]
copied slice s1 : [0 0 0 0 0]
copied slice s2 : [0 0 0 0 0 0 0 0 0 0]
分析: 函数 copy 在两个 slice 间复制数据,复制长度以 len 小的为准。
例:
package main
import (
"fmt"
)
func main() {
data := [...]int{1, 2, 3}
slice := data[:]
for index, value := range slice {
fmt.Printf("inde : %v , value : %v\n", index, value)
}
}
结果:
inde : 0 , value : 1
inde : 1 , value : 2
inde : 2 , value : 3
字符串切片操作例:
package main
import (
"fmt"
)
func main() {
str := "hello world"
s1 := str[0:5]
fmt.Println(s1)
s2 := str[6:]
fmt.Println(s2)
}
结果:
hello
world
分析: string底层就是一个byte的数组,因此,也可以进行切片操作。
字符串修改例:
package main
import (
"fmt"
)
func main() {
str := "Hello world"
s := []byte(str) //中文字符需要用[]rune(str)
s[6] = 'G'
s = s[:8]
s = append(s, '!')
str = string(s)
fmt.Println(str)
}
结果:
Hello Go!
分析: string本身是不可变的,因此要改变string中的字符,需要将字符串转化成切片