一、来源
本文来源与将切片传递到子函数中对其进行append。发现在主函数中切片未被修改。而我又对切片结构深信不移,底层数组一定被修改。所以想办法获取底层数组值证明我猜想
二、代码验证
1 初始代码
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
res := make([]int,0,100)
for i:=0;i<5;i++ {
res = append(res, i)
}
PringSliceStruct(&res) // 0,1,2,3,4
addNumToRes(res)
PringSliceStruct(&res) //0,1,2,3,4
// 不应该是上面的结果,应该是0,1,2,3,4,5,6,7,8,9?我疑问?
addNumToRes2(res)
PringSliceStruct(&res) //100,101,102,103,104
}
func addNumToRes(res []int) {
for i:=10;i<20;i++ {
res = append(res, i)
}
PringSliceStruct(&res) // 0,1,2,3,4,5,6,7,8,9
}
func addNumToRes2(res []int) {
for i:=0;i<10;i++ {
res[i]= i+100
}
PringSliceStruct(&res)//100,101,102,103,104
}
func PringSliceStruct(s *[]int) {
ss := (*reflect.SliceHeader)(unsafe.Pointer(s))
fmt.Printf("slice struct:%+v, slice is %v\n", ss, s)
}
2、换方法打印
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
res := make([]int,0,100)
for i:=0;i<10;i++ {
res = append(res, i)
}
addNumToRes(res)
fmt.Println(res)
// 通过反射获取切片的底层数组地址
// 通过内存地址+元素长度打印出所有值
sliceValue := reflect.ValueOf(res)
arrayAddr := unsafe.Pointer(sliceValue.Pointer())
for i := 0; i < 25; i++ {
elementAddr := unsafe.Pointer(uintptr(arrayAddr) + uintptr(i)*unsafe.Sizeof(res[0]))
element := *(*int)(elementAddr)
fmt.Println("Element", i, ":", element)
}
}
func addNumToRes(res []int) {
for i:=10;i<20;i++ {
res = append(res, i)
}
}
// 输出
// [0 1 2 3 4]
//Element 0 : 0
//Element 1 : 1
//Element 2 : 2
//Element 3 : 3
//Element 4 : 4
//Element 5 : 5
//Element 6 : 6
//Element 7 : 7
三、总计
slice传递是值传递,但是底层数组不变。仍然被修改 但是主函数中slice的len固定,只能获取到一段,所以打印的数据没有变化