众所周知 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,函数或者通道,那么修改形参就会对应修改实参