jjzjj

go - 关于Go语言初始化(执行)顺序的问题

coder 2024-07-08 原文

我是 Go 的新手。当运行多个 go 文件时,包括包、变量和 init 函数,我卡在了初始化序列中。

据我所知,有几个规则:

  1. 导入的包和init函数应该根据它们出现的顺序被调用。

  2. 如果A文件导入B文件,B文件导入C文件,则初始化顺序为C->B->A。

  3. 依赖总是先执行。

  4. main 包总是最后执行。

有一个例子让我很困惑(我被告知初始化顺序是由小数到大数表示的,比如1.1先执行1.2,1.2先执行2.1等等)

// p1.go

package p1

import "fmt"         //1.1

var x float32 = 1.2   //1.2

func init()  {        //1.3

       fmt.Printf("p1 package, x:%f\n", x)    //1.4
}

func Donothing() {

       fmt.Println("do nothing.\n")
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// a.go

package main

import "fmt"

var WhatIsThe1 = AnswerToLife(2.1) //2.1
var WhatIsThe2 = AnswerToLife(2.2) //2.2
var WhatIsThe3 = AnswerToLife(2.3) //2.3

func init() { //3.1


       fmt.Printf("init WhatIsThe in a.go `s init 3.1: %d\n", 2)

}

func init() { //3.2


       fmt.Printf("init WhatIsThe in a.go`s init 3.2: %d\n", 3)

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// testinit.go

package main

import "p1" //1
import "fmt"

var WhatIsThe4 = AnswerToLife(2.4) //2.4
var WhatIsThe5 = AnswerToLife(2.5) //2.5
var WhatIsThe6 = AnswerToLife(2.6) //2.6

func AnswerToLife(index float32) float32 {

       fmt.Printf("init package level variable, WhatIsThe: %f\n", 
index)
       return index
}

func init() { //3.3

       fmt.Printf("init WhatIsThe in testinit.go`s init3.3: %d\n", 0)

}

func init() { //3.4

       fmt.Printf("init WhatIsThe in testinit.go`s init3.4: %d\n", 1)

}

func main() { //4

       p1.Donothing() //5
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// z.go

package main

import "fmt"

var WhatIsThe7 = AnswerToLife(2.7) //2.7
var WhatIsThe8 = AnswerToLife(2.8) //2.8
var WhatIsThe9 = AnswerToLife(2.9) //2.9

func init() { //3.5


       fmt.Printf("init WhatIsThe in z.go`s init 3.5: %d\n", 4)

}

func init() { //3.6


       fmt.Printf("init WhatIsThe in z.go`s init 3.6: %d\n", 5)

}

我对那些事情感到困惑:

  1. 当一个文件正在声明包 main 时,它可以缺少 main 函数吗?

  2. 如果有多个包main(s),它们之间的关系是什么?

  3. 我从其他语言(如 Python、Javascript 等)了解到,应该有一个“主文件”。 Go语言怎么样?

  4. 所有包main(s)的初始化顺序是什么?

  5. 我对序列 2.1 ~ 2.9 感到困惑,为什么它们是顺序执行的,而不是执行文件 a.go 中的那些 init 函数, testinit.goz.go?

最佳答案

specification说:

A complete program is created by linking a single, unimported package called the main package with all the packages it imports, transitively. The main package must have package name main and declare a function main that takes no arguments and returns no value.

func main() { … }

Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.

请注意,主包和名称为 main 的包之间存在区别。

  1. 主包必须在包文件中包含一个main 函数。否则,名为 main 的包中的文件不需要具有 main 函数。

  2. 程序从上面定义的主包开始执行。其他名为 main 的包没有特殊状态。

  3. 可以有多个main 包。只有一个包将满足主包的要求。

  4. 包初始化顺序取决于包之间的导入关系。任何包的名称都不会在确定初始化顺序方面发挥任何作用。

关于go - 关于Go语言初始化(执行)顺序的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55658556/

有关go - 关于Go语言初始化(执行)顺序的问题的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  5. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  6. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  7. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  8. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  9. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  10. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

随机推荐