看过很多文章,都说切片(slice)是引用类型, 但是实际操作中很难通过结果来证明是引用类型,特别是使用 append 函数时,打印切片结果还是没有变化。 现在我们来使用 unsafe.Pointer 来修改切换的 len 属性来证明切片是引用类型。 废话不多说,上代码...
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
s := make([]int, 0, 5)
// 初始化切片数据
s = append(s, 1, 2, 3)
// 调用appendSlice方法,给切片添加数据
appendSlice(s)
// 打印切片
fmt.Println(s) // 输出:1 2 3 (说明增加的 100 没有在这儿体现出来)
// 现在我们来使用黑科技,来证明切片是引用类型
sh := (*reflect.SliceHeader)(unsafe.Pointer(&s))
sh.Len = 4
// 现在重新打印
fmt.Println(s) // 输出: 1 2 3 100 (现在看到100, 是不是就是说明 appendSlice 方法的修改,已经影响到了外面的slice了,也就证实了slice是引用类型哦)
}
func appendSlice(s []int) {
s = append(s, 100)
}
补充说明
注意,追加的切片数据不能超过容量哦,不然会引起切片底层数组指针指向新的数组地址,那就不能看出效果了。