您的位置 首页 golang

来聊聊golang中的引用传值和拷贝传值

 type Person struct {
Name string
Cars []string
}
// TestArgs 测试参数传递
func TestArgs(*testing.T) {
{
// 普通的变量,非指针类型的就不演示了,肯定是拷贝传递
// 这里有个特例,就是结构体中,如果包含像slice或map类型,其值是引用传递
}
{
// 来看看普通的整形引用传值
var a int = 1
fmt.Printf("before updateInt:%+v \n", a)
updateInt(&a)
fmt.Printf("after updateInt:%+v \n", a)
// 结果是:
// before updateInt:1
// after updateInt:2
//
// 解释:如果参数为指针,则会改变原来的值
}
{
// 来看看数组,发现是拷贝传值,这个有点出乎意料
a := [2]string{"a", "b"}
fmt.Printf("before updateArray:%+v \n", a)
updateArray(a)
fmt.Printf("after updateArray:%+v \n", a)
// 打印结果:
// before updateArray:[a b]
// after updateArray:[a b]
}
{
// 来看看普通的slice传值,发现值引用传值
s := []int{1, 2}
fmt.Printf("before updateSlice-1:%+v \n", s)
updateSlice(s)
fmt.Printf("after updateSlice-1:%+v \n", s)
// 打印的结果
// before updateSlice:[1 2]
// after  updateSlice:[2 2]
//
// 解释: 可以看到当参数为slice时,改变成员的值会改变原始值
// 因为s仍然指向原来的地址,如果要避免,可以重新定义一个切片:
// d:=make([]int,2)
// copy(d,s)
}
{
// 来看看结构体包含切片slice成员变量,发现是引用传值
var person Person
person.Name = "123"
person.Cars = append(person.Cars, "tesila")
fmt.Printf("before update struct's slice:%+v \n", person.Cars)
updatePerson(person)
fmt.Printf("after update struct's slice:%+v \n", person.Cars)
// 打印结果:
// before update struct's slice:[tesila]
// after update struct's slice:[xiaopeng]
//
// 解释:当传递的值包含有切片时,调用后改变切片的值,仍然会改变原始值
}

{
// 来看看map集合,发现map是引用传值
a := map[string]string{
"a": "a",
}
fmt.Printf("before updateMap:%+v \n", a)
updateMap(a)
fmt.Printf("after updateMap:%+v \n", a)
// 打印结果:
// before updateMap:map[a:a]
// after updateMap:map[a:b]
}
}
// 更新整数的值
func updateInt(a *int) {
*a = 2
}
// 更新切片成员变量的值
func updateSlice(s []int) {
s[0] = 2
}

// 更新结构体slcie成员变量
func updatePerson(p Person) {
p.Cars[0] = "xiaopeng"
}

// 更新map的key值
func updateMap(m map[string]string) {
m["a"] = "b"
}

// 更新数组成员的值
func updateArray(a [2]string) {
a[0] = "b"
}  

怎么样,有出乎你的意料吗……

文章来源:智云一二三科技

文章标题:来聊聊golang中的引用传值和拷贝传值

文章地址:https://www.zhihuclub.com/98995.shtml

关于作者: 智云科技

热门文章

网站地图