GO切片传值/引用/指针

GO切片传值/引用/指针

鄙人一直以为切片,map 在函数调用过程中传递是引用传递。这一点没错。和大家想的一样
但是此处有一个坑需要规避

就是 当所传原切片长度变大后。就是增长后,Go底层会为其分配新的地址来存储更多的值,这时候你传的原切片地址就会变成新的。

原理:

append()添加数据时并不会影响实参(的长度)。 (可以通过返回值覆盖(修改)实参的值(长度);或者通过切片的指针修改实参)

因此当函数中对原切片的长度进行扩增,调用append后,地址发生了变化。在不做返回值覆盖的情况下,需要传入原切片的指针。


package main
 
import "fmt"
 
// 值传递:改变形参的值,并不会改变实参的值。(例如:数组、结构体)
// 地址传递(引用传递):改变形参的值,会影响到实参的值。(例如:切片、map、指针)(切片变量名本身就是一个地址)
 
// 数组作为函数的参数,是值传递。 修改形参不会改变实参的值。(可以通过返回值来覆盖(修改)实参的值)
// 切片的数据存放在内存的堆区。 数组的数据(函数的局部变量)存放在内存的栈区
 
func main() {
	// 定义切片。
	slice := []int{0, 1, 2, 3, 4}
	test(slice)
	fmt.Printf("%p \n", slice) // 0xc000072030
	fmt.Println(slice)   // [111 1 2 3 4]  (修改形参会影响到实参)
}
 
// 切片作为函数的参数(地址传递) (切片变量名本身就是一个地址)
func test(s []int) {
	fmt.Printf("%p \n", s) // 0xc000072030 与实参的地址相同
	s[0] = 111     // 修改形参会影响到实参
 
	***

//但是 append()添加数据时并不会影响实参(的长度)。 (可以通过返回值覆盖(修改)实参的值(长度);或者通过切片的指针修改实参)***

	s = append(s, 66,77,88)
}

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页