Variable declaration across files

November 13, 2024

Package initialization

The declaration order of variables declared in multiple files is determined by the order in which the files are presented to the compiler: Variables declared in the first file are declared before any of the variables declared in the second file, and so on. To ensure reproducible initialization behavior, build systems are encouraged to present multiple files belonging to the same package in lexical file name order to a compiler.

This paragraph does not affect the validity of a program. That is to say, if we take the example from last week:

var x = a
var a = 3

but spread it across files, it will still compile just fine:

Given a.go:

package foo

var x = a

and b.go:

package foo

var a = 3

Both of the following will work:

go build a.go b.go
go build b.go a.go

What changes is the runtime declaration of the variables. We can see this in action with the following two source files:

a.go:

package main

func main() {}

var a = func() {
  println("a")
  return 3
}()

b.go:

package main

var b = func() {
  println("b")
  return 7
}()

Now run them with the files compiled in different order:

$ go run a.go b.go
a
b
$ go run b.go a.go
b
a

Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


init functions

We’ve been looking at the order of package variable initialization. What if these rules are confusing? Or even non-desterministic for you? Or maybe you simply want to do something more advanced than is feasible in package variable declarations. Is there an alternative? There is! Package initialization … Variables may also be initialized using functions named init declared in the package block, with no arguments and no result parameters. func init() { … } Note that package variables can be initialized, but not declared within an init function.


When package variable initialization order isn't defined

We’re nearing the end of the discussion on package initialization order. Monday should be the last day on that topic, but more on that shortly. Up to now, we’ve been looking at the deterministic order-of-initialization rules.Today’s topic is when that order is not defined. Package initialization … Dependency analysis is performed per package; only references referring to variables, functions, and (non-interface) methods declared in the current package are considered. If other, hidden, data dependencies exists between variables, the initialization order between those variables is unspecified.


Package variable dependency analysis

Today’s section of the spec is a bit dense and technical. But don’t worry, it makes a lot of sense once we get to the end. Package initialization … Dependency analysis does not rely on the actual values of the variables, only on lexical references to them in the source, analyzed transitively. For instance, if a variable x’s initialization expression refers to a function whose body refers to variable y then x depends on y.

Get daily content like this in your inbox!

Subscribe