liveBook · Manning

Global variable

As explained in 100 Go Mistakes and How to Avoid Them

A global variable is a variable whose scope allows access from multiple functions or locations within a package or program.

A global variable can be accessed from multiple functions or locations, but that convenience creates hidden coupling: any function in the package can alter it, making dependent unit tests harder to isolate. section 2.3.2

var db *sql.DB
 
func init() {
    dataSourceName :=
        os.Getenv("MYSQL_DATA_SOURCE_NAME")       #1
    d, err := sql.Open("mysql", dataSourceName)
    if err != nil {
        log.Panic(err)
    }
    err = d.Ping()
    if err != nil {
        log.Panic(err)
    }
    db = d                                        #2
}

This database example stores a connection pool in the package-level variable db after init performs connection setup and panics on failure. section 2.3.2

Using a global database connection from init is often a mistake. init cannot return an error, so it must panic; it also runs before tests, even when a test does not need the connection. A plain createClient function instead returns the error to its caller, which can choose retries, fallbacks, or termination. section 2.3.2

func createClient(dsn string) (*sql.DB, error) {    #1
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        return nil, err                             #2
    }
    if err = db.Ping(); err != nil {
        return nil, err
    }
    return db, nil
}

This replacement encapsulates database creation in a callable function and returns failures instead of assigning the connection to global state. section 2.3.2

Preventing a benchmark from disappearing

A global variable has a narrow, deliberate use in benchmarks. Store each function result in a local variable during the loop, then assign the final value to a global variable after the loop. The local assignment limits per-iteration overhead, while the global assignment gives the compiler an observable result and prevents inlining or dead-code elimination from making the benchmark effectively empty. section 11.8.3

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains mutation, test isolation, initialization errors, and benchmark optimization, stopping short of broader state-management patterns.
Examples
Uses a global database connection pool and a benchmark sink paired with a local result variable.
What you can do after
Diagnose hidden test coupling and misleading benchmarks, then replace global initialization with caller-controlled functions when appropriate.
How it connects
Connects global variables to init functions, error handling, unit testing, benchmarking, compiler optimizations, and local variables.

Also explained in

Compare how 12 books explain global variable →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.