声明struct的变量与将空结构分配给变量有什么区别

声明struct的变量与将空结构分配给变量有什么区别,struct,go,Struct,Go,在第一行中,tom被声明为person,第二行中,jim被声明为person并为其分配了一个空的person,这两者之间有什么区别?默认值在两种方式中都是相同的。第1行是否会在声明后分配内存而不分配任何内容 一模一样 type person struct { age int gender string } (1)var tom person (2)var jim person = person{} 上面的代码是分配内存还是仅仅表示这样做的地址 var i int 我知道

在第一行中,tom被声明为person,第二行中,jim被声明为person并为其分配了一个空的person,这两者之间有什么区别?默认值在两种方式中都是相同的。第1行是否会在声明后分配内存而不分配任何内容

一模一样

type person struct {
    age    int
    gender string
}
(1)var tom person
(2)var jim person = person{}
上面的代码是分配内存还是仅仅表示这样做的地址

var i int
我知道I变量在这两个代码中有不同的含义,第一个是int类型的变量,第二个是指针,但第一个I也应该表示内存中的某个地址,这意味着它将某个地址分配给I,并将“I”默认为0?

声明变量与用零值初始化变量 在Go中,所有未声明初始值设定项的变量都被初始化为适合其类型的所谓零值。因为对于结构
person
来说,它的零值是表达式
person{}
这两种情况下,(1)和(2)做相同的事情。我估计编译器会为它们生成相同的代码

引用:

变量声明创建变量,将标识符绑定到该变量,并为其提供类型和可选的初始值

如果给出了表达式列表,则通过将表达式按顺序分配给变量来初始化变量;必须使用所有表达式,并从中初始化所有变量。否则,每个变量都将初始化为其初始值

通过声明变量来分配内存 声明
var i int
声明一个变量并初始化它。在某种意义上,这确实意味着分配内存(并初始化它),但我不会深入挖掘:编译器将安排变量存在,这一事实应该让您满意

至于“表示地址”与否,则取决于您如何看待这个问题:考虑变量在内存中的布局与程序员无关。变量的名称是其值的句柄,编译器可以随意提供这种访问。我的意思是,编译器可能会在内部将这个变量的地址存储在某个地方并使用它,但您不应该关心它

var i*int=new(int)
声明声明一个指向匿名变量的指针(一个内存块,它具有特定类型“附加”的语义),用适合其类型的零值初始化该变量的内存,然后将该内存块的地址分配给要声明的变量

引用:

内置函数
new
采用类型
T
,并返回类型
*T
的值。按照初始值一节中的说明初始化内存

在这种情况下,您操作的是指针,而不是变量本身。所以这两个声明做了完全不同的事情,因为它们声明了不同类型的变量,结果变量具有不同的语义


var i int
var p*int=new(int)
之间的主要区别可能在于,在前一种情况下,变量是“立即”(静态)创建的,而在后一种情况下,匿名变量的内存是动态初始化的。但也不要过于依赖于此:当执行命中
var i int
声明时,除了名为
i
int
类型变量变为可用之外,您无法确定程序中到底发生了什么。例如,编译器可以自由地使用“堆”来分配它,而不是“堆栈”(假设采用典型的H/W体系结构)。

虽然
tom
jim
的定义具有相同的效果,但它们产生不同的机器代码。我将这两个声明放入一个简单的函数中,使用
go工具6g-S foo.go
对其进行编译,并获得这两个声明的输出程序集:

var i *int = new(int)
因此,堆栈上的空间已在堆栈上为每个变量分配,但
tom
通过将零存储到其内存来初始化,而
jim
则通过从其他内存(可能是程序只读数据段中的某个内存)复制来初始化。在大多数情况下,这可能无关紧要:如果变量初始化是程序运行时的一大部分,那么您可能做得不多

但是,如果您有一个特别大的变量(例如,一个大数组),并希望将其初始化为零值,您可能会开始看到差异

0004 (foo.go:8) TYPE    tom+-48(SP){"".person},$24
0005 (foo.go:8) TYPE    jim+-24(SP){"".person},$24
0006 (foo.go:9) LEAQ    tom+-48(SP),DI
0007 (foo.go:9) MOVQ    $0,AX
0008 (foo.go:9) STOSQ   ,
0009 (foo.go:9) STOSQ   ,
0010 (foo.go:9) STOSQ   ,
0011 (foo.go:10) LEAQ    statictmp_0000+0(SB),BX
0012 (foo.go:10) LEAQ    jim+-24(SP),BP
0013 (foo.go:10) MOVQ    BP,DI
0014 (foo.go:10) MOVQ    BX,SI
0015 (foo.go:10) MOVSQ   ,
0016 (foo.go:10) MOVSQ   ,
0017 (foo.go:10) MOVSQ   ,