【golang】slice底层函数传参原理易错点
2020-04-22 本文已影响0人
dongzd
切片底层结构
切片的底层结构主要包括引用数组的地址data,切片长度len与切片容量cap。
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
以切片为参数调用函数
Go语言中,如果以切片为参数调用函数时,有时候会给人一种参数采用了传引用的方式的假象:因为
在被调用函数内部可以修改传入的切片的元素。
任何可以通过函数参数修改调用参数的情形,都是因为函数参数中传人了指针参数(只有底部结构有指针地址类型,都可以改变原值,因为虽然函数拷贝了参数的地址,但地址指向一个内存,所以能修改原来值)
func add(arr []int) {
arr[0] = 99
}
func main() {
var a = make([]int, 2, 8)
add(a)
fmt.Println(a)
}
因为add函数修改了指针指向内存的值,所以输出:
[99,0]
如果一切都为了说明以上特性,那这边文章将毫无意义,所以但是,但是................................................
切片传入函数,不仅结构中地址指针拷贝了一份,len与cap的值也拷贝了一份,重点来了
如果在函数内部改变的切片的长度或者容量,将不改变原先的值
如以下用法:
func add(arr []int) {
arr = append(arr, 10)
}
func main() {
var a = make([]int, 2, 8)
add(a)
fmt.Println(a)
}
因为函数内部改变了len,这里的输出仍然是:
[0,0]
那该怎样通过函数即便改变了len与cap也能改变切片呢?
其实很简单,仿照append()方法,返回操作切片
arr = add(arr)