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

我正在编写一个Google App Engine Go应用程序。在其中,我想在不同的.go文件中分别处理一些调用。我应该在每个文件中分别调用“ init()”函数,还是只在一个文件中声明它,然后调用其他函数来初始化每个.go文件?


例如,如果我有两个文件,则user.go:


package User


import(

    "http"

    "fmt"

)


func init() {

    http.HandleFunc("/", hello)

}


func hello(w http.ResponseWriter, r *http.Request) {

    fmt.Fprint(w, "Hello, user!")

}

和admin.go:


package Admin


import(

    "http"

    "fmt"

)


func init() {

    http.HandleFunc("/admin/", hello)

}


func hello(w http.ResponseWriter, r *http.Request) {

    fmt.Fprint(w, "Hello, admin!")

}

这样的初始化是正确的,还是建议不要使用这种方法?


波斯汪
浏览 262回答 2
2回答

德玛西亚99

根据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中运行,所以您的问题的答案是:是的,这样的初始化是正确的。

浮云间

我认为您的问题确实是包装设计之一。我不能完全按照您的问题说出来,但是您可能还会混淆软件包和源文件。需要说明的是:一个包由一个目录中的一个或多个源文件组成,定义了一个逻辑功能单元,包括公共API和数据的内部私有表示。如果您对init()的细节感兴趣,请参阅规范的相关部分。通过为所有包级变量分配初始值,然后使用名称和签名调用任何包级函数来初始化不导入的包func init()在其来源中定义。您在上面的代码中定义了两个包,因此以下内容也适用:如果程序包已导入,则在初始化程序包本身之前先初始化导入的程序包。这表明是否有Admin对User的依赖关系(反之亦然)将确定两个init()调用的执行顺序。没有这种依赖性将导致未指定顺序执行init()调用。但是,考虑到您拥有的代码,您实际上并不关心它们执行的顺序。因此,实际上取决于您是否真的需要两个软件包,或者是否可以使用一个软件包(可能需要两个单独的源文件)。您可能会问自己一些问题:是否有两个独立的(业务)功能要表示?您是否需要提供单独的公共API?是否出于组织原因而将不同的程序包(不同的编码器)分开?您是否打算在一个或多个软件包中独立于另一个使用复用代码?
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go