6

我很好奇一些各种类型的表达式的顺序,所以我在顶层声明层尝试了这段代码,认为它会失败,但发现它可以工作:

http://play.golang.org/p/CfP3DEC5LP

var x = func() *Foo {
    fmt.Println(f) // prints &{foobar}
    return f
}()

var f = &Foo{"foobar"}

type Foo struct {
    bar string
}

请注意:

  • 声明在type Foo struct底部

  • type声明之前有一个var f声明和&Foo{]赋值

  • var声明之前,有一个立即调用的函数,它引用并返回f变量。

&Foo{}尽管即使它发生在声明之前,我也可以创建一个值并没有让我感到太惊讶,但令我感到惊讶的是,我可以在赋值之前type Foo struct成功引用并打印该值。f

这是一种可靠且特定的行为吗?我在规范中找不到对这种排序的任何引用,但也许我忽略了它。

4

1 回答 1

10

请参阅Go 编程语言参考

在一个包内,初始化包级变量,并确定常量值,根据引用顺序:如果A的初始化器依赖于B,则A将设置在B之后。依赖分析不依赖于实际值正在初始化的项目,仅在它们在源中出现时。如果 A 的值包含对 B 的提及、包含其初始值设定项提及 B 的值或提及提及 B 的函数,则 A 依赖于 B。如果这样的依赖形成一个循环,那就是错误的。如果两个项目不相互依赖,它们将按照它们在源中出现的顺序进行初始化,可能在多个文件中,如呈现给编译器的那样。由于依赖关系分析是按包进行的,因此如果 A'

于 2013-05-31T19:49:41.587 回答