变量是否需要赋默认值?

14
在Go语言中,当变量被声明时,它会被初始化为零值,如规范所述。

http://golang.org/ref/spec#The_zero_value

但是,如果需要使用默认值来初始化变量,不明确地初始化变量并利用该属性是否是良好的编码实践呢?

例如,在以下示例中:

http://play.golang.org/p/Mvh_zwFkOu

package main

import "fmt"

type B struct {
    isInit bool
    Greeting string
}

func (b *B) Init() {
    b.isInit = true
    b.Greeting = "Thak you for your time"
}

func (b *B) IsInitialized() bool {
    return b.isInit
}

func main() {
    var b B
    if !b.IsInitialized(){
        b.Init()
    }
    fmt.Println(b.Greeting)
}

程序依赖于布尔类型的默认值为 false。

1
此外,如果您运行golint,它会建议您删除额外的赋值,因为它是默认值。这是一个很好的工具,可以帮助您开始使用Go的风格。 - LanceH
3个回答

8
只有在想要使用短声明语法时,才将变量初始化为其零值。
//less verbose than ''var count int''
count := 0
empty := ""

否则,显式初始化它们只是噪音。 你可能认为未初始化的变量有问题......你是对的。幸运的是,在Go语言中没有这样的问题。零值是规范的一部分,它们不会突然改变。

8
众所周知,这里的规范很清楚:所有内存都被初始化(清零)。你应该像标准包一样利用它。特别是,它允许您依赖于自己类型的“默认构造函数”,并经常跳过New() *T类型的函数,而选择&T{}
标准包中的许多类型都利用了这一点,以下是一些示例:

http.Client

一个客户端是一个HTTP客户端。它的零值(DefaultClient)是一个可用的客户端,使用DefaultTransport。
然后你会发现在包中声明了var DefaultClient = &Client{}。

http.Server

一个服务器定义了运行HTTP服务器的参数。Server的零值是一个有效的配置。

bytes.Buffer

缓冲区是具有读写方法的可变大小字节缓冲区。Buffer 的零值是一个空缓冲区,可以立即使用。这很棒,因为您只需执行 var buf bytes.Buffer 就可以开始使用它。由于这个原因,您还经常会看到布尔成员变量以“否定”形式使用——例如,在 tls.Config 中 InsecureSkipVerify 不被称为 Verify,因为默认行为不会验证证书(认为我希望使用“false”或零值作为理想的默认值)。最后,回答您的问题:是的,这是好的编码实践,如果需要使用默认值初始化变量,则不要显式初始化变量。

6
当一个变量被声明时,它会自动包含其类型的默认值:int0float0.0boolfalsestring为空字符串,指针类型为nil,结构体中的元素为零等。在Go中,所有内存都被初始化!
例如:在内存中,var arr [5]int可以视为: +---+---+---+---+ | | | | | +---+---+---+---+ 0 1 2 3 当声明一个数组时,其中的每个元素都会自动初始化为该类型的默认零值,在这里所有元素默认为0。
因此,最好不要使用默认值进行初始化,除非您明确想要声明一个带有默认值的变量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接