You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言如何调整包执行顺序 解决包级代码提前执行取值错误问题

问题原因分析

你遇到的是Go语言包初始化执行顺序的问题,Go的程序启动执行顺序是固定的:

  • 先递归完成所有被导入依赖包的初始化(包级变量赋值、init函数执行都属于初始化阶段逻辑)
  • 所有依赖包初始化完成后,才会执行main包的初始化,最后执行main函数

你在包B中写的_ = do_something_else()属于包级别的赋值语句,是包B初始化逻辑的一部分,会在导入包B的时候(main函数运行前)就执行,此时你还没调用A.Do_something(),A.Something还是int类型的默认初始值0,所以会打印0,加time.Sleep完全无效,因为初始化阶段早于main函数所有逻辑,sleep不会改变执行顺序。
另外你代码里还有一个小问题:打印带占位符的内容应该用fmt.Printf而不是fmt.Println,否则%s会被直接作为字符串输出。

解决方案

方案1:调整调用时机(最推荐)

把包B的包级do_something_else()调用移除,改为你需要的时机手动调用,比如放在Some_other_function内部执行,这样就能保证调用时已经执行过A.Do_something():

package B

import (
    "example.com/this_project/A"
    "fmt"
    "strconv"
)

// 删除包级别的_ = do_something_else()语句

func do_something_else() {
    fmt.Printf("%s is the value of something\n", strconv.Itoa(A.Something))        
}

func Some_other_function() {
    do_something_else() // 调整到此处调用
    do_whatever()
}

此时main函数的执行顺序就能符合预期:先给A.Something赋值为100,再调用B的逻辑打印100。

方案2:调整包初始化逻辑

如果你确实需要在包初始化阶段执行do_something_else(),可以把A.Do_something()放到A包的init()函数中,保证A初始化阶段就完成赋值:

package A

var Something int

func init() {
    Do_something()
}

func Do_something() {
    Something = 100
}

这样B包导入A的时候,A已经完成初始化,A.Something已经是100,包B的初始化阶段调用do_something_else()就能拿到正确的值。注意该方案仅适合A.Something不需要动态赋值的场景,否则还是优先选方案1。

内容的提问来源于stack exchange,提问作者FrostyTheSouthernSnowman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 03:06:03