Part III · Functions & Errors
Blank Identifier
The underscore discards values on purpose: ignored results, side-effect imports, and compile-time interface checks.
Section 13 of 31 3 min read
Go refuses to compile unused imports and unused local variables. Java merely warns about them, if your IDE is configured to. The blank identifier _ is how you tell the compiler "I am discarding this on purpose". It can be assigned to, but never read.
Five uses of _
// 1. Discard one of several results (be deliberate about errors!)
n, _ := fmt.Sscan(input, &x)
// 2. Discard the index (or value) in a range loop
for _, msg := range messages {
process(msg)
}
// 3. Import a package only for its side effects (its init functions)
import (
_ "github.com/jackc/pgx/v5/stdlib" // registers the "pgx" database/sql driver
_ "net/http/pprof" // registers /debug/pprof/ handlers
_ "time/tzdata" // embeds the time zone database
)
// 4. Compile-time interface check (below)
var _ MessageStore = (*PostgresStore)(nil)
// 5. Keep a variable around while you are mid-refactor
_ = unusedForNowThe compile-time interface check
// Usually placed right below the type it checks
var (
_ MessageStore = (*PostgresStore)(nil)
_ MessageBroker = (*RedisBroker)(nil)
_ http.Handler = (*Router)(nil)
)
// Read it as: "a nil *PostgresStore must be assignable to a
// MessageStore". If a method is missing or its signature drifts,
// the build fails HERE, with a precise message:
//
// cannot use (*PostgresStore)(nil) (value of type *PostgresStore)
// as MessageStore value in variable declaration:
// *PostgresStore does not implement MessageStore
// (missing method Delete)n, _ := fmt.Sscan(input, &x)
var _ MessageStore = (*PostgresStore)(nil)
var _ MessageStore = (*PostgresStore)(nil), makes the compiler check that *PostgresStore still satisfies MessageStore.