1.go切片实现
具体实现请参考下面的文章
Go 切片:用法和本质
总结如下:
- 切片可以看做一个结构体,包含len,cap,和指向底层数组的指针。其中len为切片长度,cap为容量(底层数组的空间长度)。
- 复制切片的时候,新生成的切片指向的数组与原有切片相同,第一个元素开始位置和len可能不同。
如s1 := []int{1,2,3}
s2 := s1
s3 := s1[1:]
s1, s2, s3底层指向的数组相同,只是第一个元素开始位置和len,cap可能不同。
- 在上述条件下,修改一个切片元素,会影响其他切片。
2.试验
package test
import (
"testing"
"fmt"
)
func TestSliceChange(t *testing.T) {
s1 := []int{0, 1, 2, 3}
s2 := s1
s2[0] = 7
fmt.Println(s1, s2)
s3 := []int{0, 1, 2, 3}
s4 := chSlice(s3)
fmt.Println(s3, s4)
s5 := make([]int, 4, 7)
s5[0] = 0
s5[1] = 1
s5[2] = 2
s5[3] = 3
fmt.Println(s5)
s6 := chSlice(s5)
fmt.Println(s5, s6)
fmt.Println(cap(s1), cap(s2), cap(s3), cap(s4), cap(s5), cap(s6))
s6[1] = 22
fmt.Println(s5, s6)
s4[1] = 33
fmt.Println(s3, s4)
}
func chSlice(s []int) []int {
s = append(s, 9)
return s
}
返回结果如下:
=== RUN TestSliceChange
[7 1 2 3] [7 1 2 3]
[7 1 2 3] [7 1 2 3 9]
[0 1 2 3]
[7 1 2 3] [7 1 2 3 9]
4 4 4 8 7 7
[7 22 2 3] [7 22 2 3 9]
[7 1 2 3] [7 33 2 3 9]
--- PASS: TestSliceChange (0.00s)
PASS
其中,s3和s4由于执行append的时候,发生了扩容,返回的s4指向了一个新的数组。所以修改s4元素不会影响s3
切片作为形参
package main
import (
"fmt"
"testing"
)
func TestSlice(t *testing.T) {
s := []int{2,2}
chSlice(s)
fmt.Println(s)
cpSlice(s)
fmt.Println(s)
}
func chSlice(s []int) {
s = append(s, 1,1,1,1)
s[0] = 10
fmt.Println(s)
}
func cpSlice(s []int) {
s1 := []int {3,3,3,3}
copy(s, s1)
}
结果如下
=== RUN TestSlice
[10 2 1 1 1 1]
[2 2]
[3 3]
--- PASS: TestSlice (0.00s)
PASS
在函数中执行append不会改变作为形参切片
但是copy函数可以改变
网友评论