结构体的零值

huangapple go评论73阅读模式
英文:

Struct's zero value

问题

这是示例代码:

package main

import (
	"fmt"
)

type A struct {
	Name string
}

func (this *A) demo(tag string) {
	fmt.Printf("%#v\n", this)
	fmt.Println(tag)
}

func main() {
	var ele A
	ele.demo("ele are called")

	ele2 := A{}
	ele2.demo("ele2 are called")
}

运行结果:

&main.A{Name:""}
ele are called
&main.A{Name:""}
ele2 are called

看起来var ele Aele2 := A{}是相同的。

所以,结构体的零值不是nil,而是一个所有属性都初始化为零值的结构体。这个猜测正确吗?

如果猜测正确,那么var ele Aele2 := A{}的本质是相同的,对吗?

英文:

Here is sample code:

package main

import (
    "fmt"
)

type A struct {
    Name string
}

func (this *A) demo(tag string) {
    fmt.Printf("%#v\n", this)
    fmt.Println(tag)
}

func main() {
    var ele A
    ele.demo("ele are called")

    ele2 := A{}
    ele2.demo("ele2 are called")
}

Run results:

&main.A{Name:""}
ele are called
&main.A{Name:""}
ele2 are called

It looks like those are the same about var ele A and ele2 := A{}

So, the struct's Zero value is not nil, but a struct that all of the property are initialized Zero value. Is the guess right?

If the guess is right, then the nature of var ele A and ele2 := A{} are the same right?

答案1

得分: 72

为什么要猜测(正确的话)当有一些文档可以参考呢?

> 当为变量分配存储空间时,无论是通过声明、调用new,还是创建新值(通过复合字面量或调用make),且没有提供显式初始化时,变量或值都会被赋予默认值。
>
> 这样的变量或值的每个元素都被设置为其类型的零值:
>
> * 布尔类型为false
> * 整数类型为0
> * 浮点数类型为0.0
> * 字符串类型为""
> * 指针、函数、接口、切片、通道和映射类型为nil
>
> 这种初始化是递归进行的,因此,例如,如果没有指定值,结构体数组的每个元素的字段都将被清零。

请注意,无法将结构体值设置为nil(但可以将指向结构体的指针的值设置为nil)。

英文:

Why guess (correctly) when there's some documentation ?

> When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value.
>
> Each element of such a variable or value is set to the zero value for its type:
>
> * false for booleans,
> * 0 for integers,
> * 0.0 for floats,
> * "" for strings,
> * and nil for pointers, functions, interfaces, slices, channels, and maps.
>
> This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.

Note that there's no way to set a struct value to nil (but you could set the value of a pointer to a struct to nil).

答案2

得分: 11

我不认为得票最高的答案清楚地回答了这个问题,所以这里有一个更清晰的解释:

“如果没有指定值,数组或结构体的元素将会被初始化为零值。这种初始化是递归进行的。”

来源

英文:

I don't believe the top-voted answer is clearly worded to answer the question, so here is a more clear explanation:

"The elements of an array or struct will have its fields zeroed if no value is specified. This initialization is done recursively:"

Source

答案3

得分: 2

展示了@Denys Séguret的一流答案。这样一个变量或值的每个元素都被设置为其类型的零值(https://golang.org/ref/spec#The_zero_value):

package main

import "fmt"

func main() {
    // 布尔类型为 false,
    var bl bool // false
    // 数值类型为 0,
    var in int // 0
    // 字符串类型为 "",
    var st string // ""
    // 指针、函数、接口、通道类型为 nil,
    var pi *int    // <nil>
    var ps *string // <nil>
    var fu func()      // <nil> Go vet 错误。https://stackoverflow.com/a/56663166/12817546
    var ir interface{} // <nil>
    var ch chan string // <nil>
    fmt.Println(bl, in, st, pi, ps, fu, ir, ch)
    // 切片和映射类型为 nil。
    var sl []int          // true
    var mp map[int]string // true
    var pm *map[int]string // <nil>
    fmt.Printf("%v %v %v\n", sl == nil, mp == nil, pm)
}
英文:

Demonstrating @Denys Séguret's first-rate answer. Each element of such a variable or value is set to the zero value for its type (https://golang.org/ref/spec#The_zero_value):

package main

import &quot;fmt&quot;

func main() {
	// false for booleans,
	var bl bool // false
	//0 for numeric types,
	var in int // 0
	// &quot;&quot; for strings,
	var st string // &quot;&quot;
	// and nil for pointers, functions, interfaces, channels,
	var pi *int    // &lt;nil&gt;
	var ps *string // &lt;nil&gt;
	var fu func()      // &lt;nil&gt; Go vet error. https://stackoverflow.com/a/56663166/12817546
	var ir interface{} // &lt;nil&gt;
	var ch chan string // &lt;nil&gt;
	fmt.Println(bl, in, st, pi, ps, fu, ir, ch)
	// slices, and maps.
	var sl []int          // true
	var mp map[int]string // true
	var pm *map[int]string // &lt;nil&gt;
	fmt.Printf(&quot;%v %v %v\n&quot;, sl == nil, mp == nil, pm)
}

huangapple
  • 本文由 发表于 2015年2月20日 17:41:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/28625794.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定