golang中,指针解引用其成员变量的问题

type nameage struct {
name string
age int
}
na:=new(nameage)
(*na).age=25
//na.age=25
(*na).name="ddj"
//na.name="ddj"
fmt.Println((*na).name)
fmt.Println(na.name)

以上代码,我发现 (*na).age na.age 的作用是一样的,打印出来的结果也是一样的。


但是从语法上来看,我认为 (*na).name 才是合法的,因为 na 是一个指针,age和name都是nameage的成员变量,应该先 (*na) 来获取对象,然后再去获取这个对象的成员。


我不知道为什么结果都一样,是go自动处理掉了?还是有其他说法?

已邀请:

littledriver

赞同来自: ddxx11223

我建议你可以看一下 go 是怎么实现 oop 或者如何传递函数参数的。目前为止,我认为你碰到的问题是,new 出来的是一个指针,访问对象属性的时候应该使用指针解引用,但是na.name却也是可以的。 go 语言中,在调用一个类对象的成员的时候,无论是方法还是属性,都会做一个自动的转换,并把它当做成第一个参数传递进去。


先说一下这个自动的转换,在调用对象方法的时候可能这个现象更加明显。比如


func (n *nameage) PrintName(){fmt.Println(n.name)}


那么无论你使用na.PrintName() 还是(*na).PrintName()都是可以的,如果函数签名中receiver是指针,那么在使用后一种形式调用的时候,会自动转换为指针的形式,也就是取地址符&。如果函数签名中receiver是单纯的对象,那么在使用前一种形式的时候就会将指针解引用转换成一个对象来进行调用。但是这种转换,是 go 本身自动完成的


再说函数参数传递。golang 在调用对象方法的时候,会把引用符号前面的对象当做是函数的第一个参数传递进去,也就是说,其实上面 PrintName 这个函数是有参数的并且第一个参数是(n *nameage),在调用的时候,比如na.PrintName, 就是PrintName(na),如果是以 *na.PrintName 这种形式调用,就是 PrintName(&(*na))。


上面讲的是对象调用方法,但是我觉得在调用其内部属性的时候也是相似的,这个答案也是通过类比的方式来解释楼主的问题。希望对楼主有所帮助

要回复问题请先登录注册