一直没发现数组与slice的区别,发现数组的命名是[...] int或[3]int,即前面的[]要有东西,而slice直接是[]int,或者make([]int)
append一定要有返回值,
当len = = cap时 append会导致扩容,底层数组不再共享,
在1024字节以内,扩容一倍,大于2014时,增加cap的1/4
go中的数组与C语言中的数组类似,但是不同的是C中的数组名其实还是指针,在作为参数传递的过程中会退化为指针,而go语言则是在编译期间就确定其大小,然后始终是作为值传递的。
初始化
[5] int {1,2,3,4,5}
[5] int {1,2}
[...] int {1,2,3,4,5}
[5] int { 2:1,3:2,4:3}
[...] int {2:1,4:3}
作为参数传递
例如:
package main
import (
"fmt"
"reflect"
)
func modifySlice(array []int) {
array[0] = 10
}
func modifyArr(array [5]int) {
array[0] = 10
}
func modifyPt(array *[5]int){ // 作为指针传递
(*array)[0] = 10
}
func main(){
arr := [...]int{1,2,3,4,5}
fmt.Println(reflect.TypeOf(arr))
modifyArr(arr)
fmt.Println("In main(), arr values:", arr)
modifyPt(&arr)
fmt.Println("In main(), arr values:", arr)
sli := []int{1,2,3,4,5}
fmt.Println(reflect.TypeOf(sli))
modifySlice(sli)
fmt.Println("In main(), sli values:", sli)
}
// 输出结果为
//[5]int
//In main(), arr values: [1 2 3 4 5]
//In main(), arr values: [10 2 3 4 5]
//[]int
//5
//In main(), sli values: [10 2 3 4 5]
从上面的例子中可以看出slice作为参数传递的是指针,因此传递速度会快很多。
但是数组作为一个固定长度的数据类型,在使用中有很多不方便的地方,因此go提供了一个很类似python 中的list的数据类型slice
从名字也能看出来slice支持切片操作
sli := []int{1,2,3,4,5}
sli = sli[:3]
还支持append操作
sli = append(sli, 6)
sli = append(sli, sli2)
如果要实现类似数组的值传递的功能,可以利用 copy 函数
sli1 := make([]int, len(sli))
copt(sli1, sli)
初始化
sli := make([]int, 5, 10) // 5 是其长度,10 是其容量(可选),分别可以通过 len(sli) cap(sli) 获取
var sli []int // sli = nil
sli := arr[:] // sli 的修改也会影响到arr
从上面的内容可以看出数组与切片有以下区别
顺便说一下,slice的数据结构类似下面:
+--------------------+
| data pointer |
+--------------------+
| len |
+--------------------+
| cap |
+--------------------+
然后扩容方式与vector类似,1024字节以下是每次cap增加一倍,1024以上是每次cap增加1/4