Unbound identifiers

June 16, 2023

There are two identifiers that we can use in Go that do not create a binding to a thing

Declarations and scope

The blank identifier may be used like any other identifier in a declaration, but it does not introduce a binding and thus is not declared. In the package block, the identifier init may only be used for init function declarations, and like the blank identifier it does not introduce a new binding.

We’ve talked about the blank identifier before in other contexts. In this context, what matters is that we can use the blank identifier for things that would normally be bound to a scope, such as within a file or function. The use of the blank identifier means that the result that would have been bound to a named identifier, is instead discarded. No binding takes place. And the blank identifier can be repeated ad nauseam without risk of re-declaring or shadowing.

func getAnswer() string {
	// The second value, an error, is discarded
	answer, _ := readAnswerFromSource()
	return answer
}

What many don’t realize is that init follows similear rules. init isn’t ignored the same way that _ is, but it doesn’t bind to anything, making it a special case of a function name that can be repeated. This is perfectly valid within the same package, or even the same file:

package main

import "fmt"

func main() {
}

func init() {
	fmt.Println("init 1")
}

func init() {
	fmt.Println("init 2")
}

Output:

init 1
init 2

See it on the playground.

Quotes from The Go Programming Language Specification Version of December 15, 2022


Share this

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

Unsure? Browse the archive .

Related Content


Unused variables

Variable declarations … Implementation restriction: A compiler may make it illegal to declare a variable inside a function body if the variable is never used. One short sentence. And people either love it, or hate it. I’m in the “love it” camp, but some people like the option to create unused variables, for later use, or during debugging. func foo() error { var i int // Some commented out code that probably used i // .


Happy New Year!

I’ve been on an unannounced, unplanned, month-long hiatus, what with moving my family across the globe. But with the new year starting, and the worst of the chaos behind me, I’m going to try to get back in the saddle again, and pick up where I left off. And what better way to initialize 2025 than with talking about init? Program initialization … Package initialization—variable initialization and the invocation of init functions—happens in a single goroutine, sequentially, one package at a time.


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.

Get daily content like this in your inbox!

Subscribe