Skip to main content

数组与切片

数组与切片的关系

数组具有相同类型的值且容量固定的集合.

关于数组,需要牢记两点:类型和长度.

go
1

在go语言中,数组是值类型.

go
1
2
3
4
5
6
7
8
9
10
11
func main() {
a := []int{1, 2, 3, 4, 5}
b := a
a[0]++
a = append(a, 20)
fmt.Println(a, b)
}

为什么a的修改会影响b,但追加a追加之后a和b的元素就不相同了呢?初步猜测是因为append函数的缘故

数组与切片底层共享

go
1
2
3
4
5
6
7
8
9
10
11
func main() {
var nums = [6]int{0, 1, 2, 3, 4, 5}
//b=[1,2],len=2,cap=5
a := nums[1:3]
a[1]++
// [0,1,3,3,4,5]
fmt.Println("a-len", len(a), "a-cap", cap(a))
fmt.Println(a, nums)
}

切片容量,为数组的长度与切片起始位置做差.

go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
//7,8
nums := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
//7,8,len=2,cap=4
a := nums[6:8]
fmt.Println("a-len", len(a), "a-cap", cap(a), a)
b := a
fmt.Println("b-len", len(b), "b-cap", cap(b), b)
a[0]++
a = append(a, 20)
fmt.Println("a-len", len(a), "a-cap", cap(a), a)
fmt.Println("b-len", len(b), "b-cap", cap(b), b)
fmt.Println(nums)
}

在使用append函数对切片追加元素时,可能会导致容量用尽而再次重新分配,此时切片会和原数组进行分离,此时有可能导致bug

当容量不足时,触发重新分配,此时会和原数组进行分割,

对切片进行append操作时对原数组的影响,取决于切片的容量,这里有两点值得注意:

  1. 关于切片容量的计算:slice_cap=array_len-slice_start_index;
  2. 对切片进行操作时是希望与原数组保持关联性还是独立性
    • 如果期望与原数组保持关联性,则append操作时需要注意切片容量限制
    • 如果期望与原数组保持独立性,最好的解决办法就是使用copy函数获取原数组的副本,对副本进行操作.

数组因为类型和容量固定,所以效率更高,