为了账号安全,请及时绑定邮箱和手机立即绑定

GAE Go,init()-多次调用?

GAE Go,init()-多次调用?

Go
波斯汪 2021-05-06 14:08:27
我正在编写一个Google App Engine Go应用程序。在其中,我想在不同的.go文件中分别处理一些调用。我应该在每个文件中分别调用“ init()”函数,还是只在一个文件中声明它,然后调用其他函数来初始化每个.go文件?例如,如果我有两个文件,则user.go:package Userimport(    "http"    "fmt")func init() {    http.HandleFunc("/", hello)}func hello(w http.ResponseWriter, r *http.Request) {    fmt.Fprint(w, "Hello, user!")}和admin.go:package Adminimport(    "http"    "fmt")func init() {    http.HandleFunc("/admin/", hello)}func hello(w http.ResponseWriter, r *http.Request) {    fmt.Fprint(w, "Hello, admin!")}这样的初始化是正确的,还是建议不要使用这种方法?
查看完整描述

2 回答

?
德玛西亚99

TA贡献1770条经验 获得超3个赞

根据Go语言规范:

  • 所有初始化代码都在单个goroutine中运行,并且

  • 单个包中的init()函数以未指定的顺序执行

在您的情况下,包User和Admin是独立的(User不导入Admin,也不Admin导入User)。这意味着:

  • User和Admin中的两个init()函数以未指定的顺序执行


将两个init()函数的主体合并到一个init()函数中,如下所示:

func init() {

    http.HandleFunc("/", User.Hello)

    http.HandleFunc("/admin/", Admin.Hello)

}

请注意,程序是先注册"/"还是都无关紧要"/admin/"。因此,以下代码也是有效的:


func init() {

    http.HandleFunc("/admin/", Admin.Hello)

    http.HandleFunc("/", User.Hello)

}

从代码上面的两个片段,我们可以看到,这是确定的http.HandleFunc("/", ...),并http.HandleFunc("/admin/", ...)在未指定的顺序调用。


因为"/"和"/admin/"可以以任何顺序进行注册,并且所有init()函数都在单个goroutine中运行,所以您的问题的答案是:是的,这样的初始化是正确的。


查看完整回答
反对 回复 2021-05-10
?
浮云间

TA贡献1829条经验 获得超4个赞

我认为您的问题确实是包装设计之一。我不能完全按照您的问题说出来,但是您可能还会混淆软件包和源文件。需要说明的是:一个包由一个目录中的一个或多个源文件组成,定义了一个逻辑功能单元,包括公共API和数据的内部私有表示。

如果您对init()的细节感兴趣,请参阅规范的相关部分。

通过为所有包级变量分配初始值,然后使用名称和签名调用任何包级函数来初始化不导入的包

func init()

在其来源中定义。

您在上面的代码中定义了两个包,因此以下内容也适用:

如果程序包已导入,则在初始化程序包本身之前先初始化导入的程序包。

这表明是否有Admin对User的依赖关系(反之亦然)将确定两个init()调用的执行顺序。没有这种依赖性将导致未指定顺序执行init()调用。

但是,考虑到您拥有的代码,您实际上并不关心它们执行的顺序。因此,实际上取决于您是否真的需要两个软件包,或者是否可以使用一个软件包(可能需要两个单独的源文件)。

您可能会问自己一些问题:

  • 是否有两个独立的(业务)功能要表示?

  • 您是否需要提供单独的公共API?

  • 是否出于组织原因而将不同的程序包(不同的编码器)分开?

  • 您是否打算在一个或多个软件包中独立于另一个使用复用代码?


查看完整回答
反对 回复 2021-05-10
  • 2 回答
  • 0 关注
  • 261 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信