type person struct {
age int
gender string
}
(1)var tom person
(2)var jim person = person{}
第一行,tom 被声明为 person,第 2 行,jim 被声明为 person,并为其分配了一个空的 person,这两者有什么区别?两种方式的默认值是相同的。请问第 1 行声明后分配内存存储而不为其分配任何内容?
与
相同var i int
上面的代码是分配内存还是仅仅表示一个地址
var i *int = new(int)
我知道这两个代码中的 i 变量有不同的含义,第一个是 int 类型的变量,第二个是指针,但是第一个 i 也应该代表内存中的某个地址,这意味着它分配了某个地址到 i 并默认“i”为 0?
最佳答案
声明变量与用零值初始化变量
在 Go 中,所有没有初始化器声明的变量都被初始化为适合其类型的所谓的“零值”。由于对于 struct person
来说,其零值是表达式 person{}
,在这两种情况下,(1) 和 (2) 都会做同样的事情。我认为编译器将为它们生成相同的代码。
引用the spec :
A variable declaration creates a variable, binds an identifier to it and gives it a type and optionally an initial value.
…
If a list of expressions is given, the variables are initialized by assigning the expressions to the variables in order; all expressions must be consumed and all variables initialized from them. Otherwise, each variable is initialized to its zero value.
通过声明变量分配内存
声明var i int
声明一个变量并初始化它。从某种意义上说,这确实意味着分配内存(并初始化它),但我不会那么深入:您应该接受编译器将安排的事实变量存在。
至于它是否“表示一个地址”取决于你如何看待这一点:考虑变量如何在内存中布局不是程序员的事——变量的名称是其值的句柄,并且编译器可以随意提供此类访问。我的意思是,编译器可能会在内部将这个变量的地址存储在某个地方并使用它,但你不应该关心它。
var i *int = new(int)
声明声明一个指向匿名变量(“附加”某种类型语义的内存块)的指针,初始化内存该变量具有适合其类型的零值,然后将该内存块的地址分配给您正在声明的变量。
引用the spec :
The built-in function
new
takes a typeT
and returns a value of type*T
. The memory is initialized as described in the section on initial values.
在这种情况下,您对指针进行操作,而不是对变量本身进行操作。因此,这两个声明做了完全不同的事情,因为它们声明了不同类型的变量,并且结果变量具有不同的语义。
可能 var i int
和 var p *int = new(int)
之间的主要区别在于,在前一种情况下,变量是“立即”创建的(静态),而在后一种情况下,匿名变量的内存是动态初始化的。但同样不要太执着于这一点:当执行命中 var i int
声明时,除了名为 i
的变量之外,您无法确定程序中到底发生了什么int
类型的 > 变得可用。例如,编译器可以自由地使用“堆”来分配它,而不是“堆栈”(假设是典型的硬件架构)。
关于struct - 声明结构变量 VS 将空结构分配给变量有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23136725/