1.go切片實現(xiàn)
具體實現(xiàn)請參考下面的文章
Go 切片:用法和本質(zhì)
總結(jié)如下:
- 切片可以看做一個結(jié)構(gòu)體,包含len,cap,和指向底層數(shù)組的指針。其中l(wèi)en為切片長度,cap為容量(底層數(shù)組的空間長度)。
- 復(fù)制切片的時候,新生成的切片指向的數(shù)組與原有切片相同,第一個元素開始位置和len可能不同。
如s1 := []int{1,2,3}
s2 := s1
s3 := s1[1:]
s1, s2, s3底層指向的數(shù)組相同,只是第一個元素開始位置和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
}
返回結(jié)果如下:
=== 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由于執(zhí)行append的時候,發(fā)生了擴容,返回的s4指向了一個新的數(shù)組。所以修改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)
}
結(jié)果如下
=== RUN TestSlice
[10 2 1 1 1 1]
[2 2]
[3 3]
--- PASS: TestSlice (0.00s)
PASS
在函數(shù)中執(zhí)行append不會改變作為形參切片
但是copy函數(shù)可以改變