go中的切片有两个特性:
type slice struct {
array unsafe.Pointer
len int
cap int
}
包括从切片和数组派生出来的切片都是公用一个底层数组的
- 当往切片append的元素超过容量时,即len(s) < cap(s)时,底层的数组会重新分配一个容量更大的数组。
- make构造出来的切片,已经预先填充了len个零值元素了。
总而言之,对切片的更改都会影响到底层的数组结构,因此需要慎重。
动手做个实验:
package main
import (
"fmt"
)
func double(s []int, count int) {
fmt.Println("函数调用内切片的长度为", len(s), " 容量为", cap(s))
for i:=0; i < count; i++ {
s = append(s, 100)
}
for i, v := range s {
s[i] = v * 2
}
}
func main() {
s := make([]int, 5, 10)
// 下面的赋值会改变s的底层数组,导致上面指定的容量10失效
// s = []int{
// 1, 2, 3, 4, 5,
// }
for i:=0; i < 5; i++ {
s[i] = i + 1
}
fmt.Println("主函数内切片的长度为", len(s), " 容量为", cap(s))
fmt.Println(s)
double(s, 1)
fmt.Println(s)
// 添加超过切片容量的元素后,double函数内切片底层的数组重新分配了,和主函数外的切片的底层数组不是同一个了,因此对其修改不会影响到主函数切片的数值
double(s, 10)
fmt.Println(s)
}
|
请发表评论