JAVA转GO 从入门到精通之实参的值传递和引用类型的区别

众所周知 Java里面的普通变量都是值传递 没有指针引用;但是GO里面有指针引用类型,那到底什么区别呢?

下面我们来看一个栗子:

type GirlFriend struct {
	Age int
	Name string
	Height int
}

// 普通实例的接收者
func (f GirlFriend) SayHello()  {
	fmt.Printf("GirlFriend: age->%d name->%s height->%d \n", f.Age, f.Name, f.Height)
}

func (f GirlFriend) ModifyHeightAndAge(age, height int)  {
	f.Age = age
	f.Height = height
	f.SayHello()
}

// 指针类型的接收者
func (f *GirlFriend) SayHelloWithPoint()  {
	fmt.Printf("Point GirlFriend: age->%d name->%s height->%d \n", f.Age, f.Name, f.Height)
}

func (f *GirlFriend) ModifyHeightAndAgeWithPoint(age, height int)  {
	f.Age = age
	f.Height = height
	f.SayHelloWithPoint()
}

对应的测试结果 大家可以先自己心里有个答案:

func TestGirlFriend_SayHello(t *testing.T) {
	type fields struct {
		Age    int
		Name   string
		Height int
	}
	tests := []struct {
		name   string
		fields fields
	}{
		// TODO: Add test cases.
		{
			name: "test1",
			fields: fields{
				18,
				"qiao",
				170,
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			f := GirlFriend{
				Age:    tt.fields.Age,
				Name:   tt.fields.Name,
				Height: tt.fields.Height,
			}
			f.SayHello() // GirlFriend: age->18 name->qiao height->170
			fmt.Printf("%+v\n", f)// {Age:18 Name:qiao Height:170}
			f.ModifyHeightAndAge(20, 168) // GirlFriend: age->20 name->qiao height->168 
			fmt.Printf("%+v\n", f)// {Age:18 Name:qiao Height:170}
			f.SayHello() // GirlFriend: age->18 name->qiao height->170 
			f.Age = 22
			f.Height = 175
			f.SayHello() // GirlFriend: age->22 name->qiao height->175 
		})
	}
}
// 普通变量的引用 打印的结果如上面所示:那大家会发现其实 普通变量应用的修改并没有生效哦 这个跟JAVA的测试结果是一样呢
// 但是指针引用类型就可以修改生效 如下所示:

func TestGirlFriend_SayHelloWithPoint(t *testing.T) {
	type fields struct {
		Age    int
		Name   string
		Height int
	}
	tests := []struct {
		name   string
		fields fields
	}{
		// TODO: Add test cases.
		{
			name: "test1",
			fields: fields{
				18,
				"qiao",
				170,
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			f := &GirlFriend{
				Age:    tt.fields.Age,
				Name:   tt.fields.Name,
				Height: tt.fields.Height,
			}
			f.SayHelloWithPoint()// Point GirlFriend: age->18 name->qiao height->170
			f.ModifyHeightAndAgeWithPoint(23, 172)// Point GirlFriend: age->23 name->qiao height->172
			f.SayHelloWithPoint() // Point GirlFriend: age->23 name->qiao height->172 
		})
	}
}

好了 相比看完这个例子大家心里有数 但是万一面试时候问了 该怎么官方的回答呢?引用《GO程序语言设计》里面的话:

每一次调用函数 都需要提供实参来对应函数的形参列表;并且形参变量都是函数的局部变量 包括返回的形参,实参是按照值传递的,所以函数接收到的都是每个实参对应的副本 另一个值一样的变量 内存地址不一样,修改形参 并不会影响调用对应的实参;然而,如果实参提供的是指针引用或者,slice,map,函数或者通道,那么修改形参就会对应修改实参

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值