Pointers 为什么指针类型的行为与结构类型不同?
我有一段Go代码,我试图分别使用两个函数Pointers 为什么指针类型的行为与结构类型不同?,pointers,go,struct,Pointers,Go,Struct,我有一段Go代码,我试图分别使用两个函数f和f2来更改结构中常规int和int的值。我不明白为什么我需要做*I来更改int的值,但当我更改结构中X的值时,我不需要这样做 type Point struct { X int } func t(i *int) { *i = 20 } func t2(p *Point) { p.X = 200 } func main() { g := 30 t(&g) fmt.Println(g)
f
和f2
来更改结构中常规int和int的值。我不明白为什么我需要做*I
来更改int的值,但当我更改结构中X的值时,我不需要这样做
type Point struct {
X int
}
func t(i *int) {
*i = 20
}
func t2(p *Point) {
p.X = 200
}
func main() {
g := 30
t(&g)
fmt.Println(g)
p := Point{3}
t2(&p)
fmt.Println(p)
}
因为
i
是*int
类型的指针,并且您想要修改所指向的对象,所以您必须编写*i
同样的语法也适用于结构,例如,您可以编写(*p).X
,但这是一个频繁的操作,因此规范允许使用p.X
,这意味着(*p).X
,没有歧义,并且是一个方便的快捷方式
它在里面
作为例外,如果x
的类型是指针类型,并且(*x).f
是表示字段(但不是方法)的有效选择器表达式,x.f
是(*x).f
的缩写
因为
i
是*int
类型的指针,并且您想要修改所指向的对象,所以您必须编写*i
同样的语法也适用于结构,例如,您可以编写(*p).X
,但这是一个频繁的操作,因此规范允许使用p.X
,这意味着(*p).X
,没有歧义,并且是一个方便的快捷方式
它在里面
作为例外,如果x
的类型是指针类型,并且(*x).f
是表示字段(但不是方法)的有效选择器表达式,x.f
是(*x).f
的缩写
考虑这两个函数最简单的方法是在
t2
函数中,使用指向底层结构的指针更改结构的字段。在t
函数中,您正在更改整个基础对象(int)
事实上,您可以编写p.X
实际上只是一个小细节。在像C这样的语言中,如果操作的是非指针变量,则只能使用p.X
。对于指针,您必须使用p->X
表示您正在使用间接方式访问字段,或者确实取消对指针的引用((*p).X
)
在内部,go仍然做同样的事情,它只允许您省略显式解引用,并且它消除了对间接运算符的需要
然而,这两种功能并不等同<代码>点是一个结构,包含一个或多个字段。另一种类型是*int
,int是单个标量值。要使t2
等效(并重新分配整个基础对象),必须将代码更改为与*int
情况下必须执行的操作相同:
func t2(p *Point) {
*p = Point{
X: 200,
Y: p.Y,
}
}
根据以下意见:TL;DR版本是指,如果访问结构类型的某个字段,则不必显式取消引用该类型的指针。您必须在C/C++中完成这项工作,但go编译器会为您解决这一问题。它表明您使用的变量是指针类型,并且编译
p.X
的方式与C编译器编译p->X
的方式相同。因此,您不需要显式地取消引用p
如果将点
声明为:
type Point struct {
X *int
}
因为表达式
p.X
的计算结果是*int
类型的操作数,需要对其进行相应处理。考虑这两个函数的最简单方法是在t2
函数中,使用指向底层结构的指针更改结构的字段。在t
函数中,您正在更改整个基础对象(int)
事实上,您可以编写p.X
实际上只是一个小细节。在像C这样的语言中,如果操作的是非指针变量,则只能使用p.X
。对于指针,您必须使用p->X
表示您正在使用间接方式访问字段,或者确实取消对指针的引用((*p).X
)
在内部,go仍然做同样的事情,它只允许您省略显式解引用,并且它消除了对间接运算符的需要
然而,这两种功能并不等同<代码>点是一个结构,包含一个或多个字段。另一种类型是*int
,int是单个标量值。要使t2
等效(并重新分配整个基础对象),必须将代码更改为与*int
情况下必须执行的操作相同:
func t2(p *Point) {
*p = Point{
X: 200,
Y: p.Y,
}
}
根据以下意见:TL;DR版本是指,如果访问结构类型的某个字段,则不必显式取消引用该类型的指针。您必须在C/C++中完成这项工作,但go编译器会为您解决这一问题。它表明您使用的变量是指针类型,并且编译
p.X
的方式与C编译器编译p->X
的方式相同。因此,您不需要显式地取消引用p
如果将点
声明为:
type Point struct {
X *int
}
因为表达式
p.X
的计算结果是*int
类型的操作数,需要进行相应的处理。所以i
是*int
类型的指针,p
是*Point
类型的指针。它们的行为不应该相同吗?@ninesat在修改指针值时,您应该始终首先编写*p
。但是,给定一个指向结构的指针,修改指向的结构的字段是一个常见的操作,因此规范允许您使用快捷方式,即您可以省略指针间接指向,但它的含义是相同的。可读性,无歧义。因此,i
是*int
类型的指针,p
是*Point
类型的指针。他们不应该表现得一样吗?