为什么在init()函数中要检查nil值?

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

Why check for nil in init()

问题

我正在阅读这篇文章,它在示例中提供了以下代码:

var templates map[string]*template.Template

// 在程序初始化时加载模板
func init() {
    if templates == nil {
        templates = make(map[string]*template.Template)
    }
}

为什么在init()函数中要检查if templates == nil?在执行到这一点时,它不总是相同的吗?

英文:

I'm reading this article which offers this code in its example:

var templates map[string]*template.Template

// Load templates on program initialisation
func init() {
    if templates == nil {
        templates = make(map[string]*template.Template)
    }

Why check for if templates == nil in init()? Won't it always be the same at this point in execution?

答案1

得分: 5

在提供的文章中,没有理由检查空值。有其他的代码结构方式。

选项1:

var templates = map[string]*template.Template{}

func init() {
    // 文章中函数中的if语句后面的代码
}

选项2:

var templates = initTemplates()

func initTemplates() map[string]*template.Template {
    templates := map[string]*template.Template{}
    // 文章中函数中的if语句后面的代码
    return templates
}

选项3:

func init() {
    templates = make(map[string]*template.Template)
    // 文章中函数中的if语句后面的代码
}

你会在Go代码中看到这些方法。我更喜欢第二个选项,因为它清楚地表明templatesinitTemplates函数中初始化。其他选项需要查找才能找到templates的初始化位置。

英文:

There is no reason to check for nil in the code provided in the article. There are other ways to structure the code.

Option 1:

var templates = map[string]*template.Template{}

func init() {
    // code following the if statement from the function in the article
}

Option 2:

var templates = initTemplates()

func initTemplates() map[string]*template.Template{} {
    templates := map[string]*template.Template{}
    // code following the if statement from the function in the article
    return templates
}

Option 3:

func init() {
    templates = make(map[string]*template.Template)
    // code following the if statement from the function in the article
}

You will see all of these approaches in Go code. I prefer the second option because it makes it clear that templates is initialized in the function initTemplates. The other options require some looking around to find out where templates is initialized.

答案2

得分: 1

《Go编程语言规范》

包初始化

变量也可以使用在包块中声明的名为init的函数进行初始化,该函数没有参数和结果参数。

func init() {  }

可以定义多个这样的函数,甚至在单个源文件中。

现在或将来,包中可能会有多个init函数。例如:

package plates

import "text/template"

var templates map[string]*template.Template

// 在程序初始化时加载项目模板
func init() {
    if templates == nil {
        templates = make(map[string]*template.Template)
    }
    // 加载项目模板
}

// 在程序初始化时加载程序模板
func init() {
    if templates == nil {
        templates = make(map[string]*template.Template)
    }
    // 加载程序模板
}

程序应该没有任何错误要进行防御性编程

<details>
<summary>英文:</summary>

&gt; [The Go Programming Language Specification][1]
&gt; 
&gt; [Package initialization][2]
&gt; 
&gt; Variables may also be initialized using functions named `init`
&gt; declared in the package block, with no arguments and no result
&gt; parameters.
&gt; 
&gt;     func init() {  }
&gt; 
&gt; Multiple such functions may be defined, even within a single source
&gt; file.

Now or in the future there may be multiple `init` functions in the package. For example,

    package plates
    
    import &quot;text/template&quot;
    
    var templates map[string]*template.Template
    
    // Load project templates on program initialisation
    func init() {
    	if templates == nil {
    		templates = make(map[string]*template.Template)
    	}
    	// Load project templates
    }
    
    // Load program templates on program initialisation
    func init() {
    	if templates == nil {
    		templates = make(map[string]*template.Template)
    	}
    	// Load program templates
    }

Programs should have zero bugs. Program defensively.

  [1]: http://golang.org/ref/spec
  [2]: http://golang.org/ref/spec#Package_initialization

</details>



huangapple
  • 本文由 发表于 2015年8月13日 00:25:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/31970689.html
匿名

发表评论

匿名网友

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

确定