Go: No globals, no init functions
Mon, May 21, 2018*Updated Sun, Jan 8, 2023: Updated install instructions to use golangci-lint instead of gometalinter.
I just created gochecknoglobals
and gochecknoinits
. The lint tools scan Go code in the current directory and error if they discover global variables or package-level init
functions.
I recently saw Dave Cheney’s tweet about not using global variables and read Peter Bourgon’s in-depth follow up A theory of modern Go. The tl;dr is magic code is bad because you need to know more about how it works than is immediate obvious from reading about it’s use, and global variables and init
functions are magic because they carry side-effects through an application that aren’t contained by the functions that use or rely on them.
@peterbourgon i present to you my thesis for "modern Go"
— Dave Cheney (@davecheney) June 6, 2017
- no side effect imports
- no package level variables
In my experience this tends to be true. Even in small apps I have worked on global variables have resulted in code that is harder to understand, and when I import a package that has an init
function it surprises me.
This has led me to avoid using globals and init
whenever I can. As an example both gochecknoglobals
contained gochecknoinits
use no globals or inits.
Install:
go install 4d63.com/gochecknoglobals@latest
go install 4d63.com/gochecknoinit@latest
Usage:
gochecknoglobals
gochecknoinits
Usage with golangci-lint
:
golangci-lint run --enable gochecknoglobals,gochecknoinits
Source: