Skip to main content
Identifiers and keywords

Identifiers and keywords

7 minutes read

Filed underGo Programming Languageon

Understand Go's naming rules, the 25 reserved keywords, and the predeclared identifiers that come built into every Go program.

What an identifier is

An identifier is the name you give to something in your program — a variable, a constant, a type, a function, a package. Every name you write in Go is an identifier.

The language spec defines exactly what characters are allowed:

  • An identifier is formed by one or more Unicode letters and Unicode digits
  • The first character must be a letter — digits are not allowed at the start
  • The underscore _ counts as a letter
age         // valid
_           // valid — the blank identifier
_count      // valid — underscore is a letter
user123     // valid — digit after the first character
café        // valid — Unicode letters are allowed
123abc      // invalid — starts with a digit
my-variable // invalid — hyphens are not letters

Go is case-sensitive. count, Count, and COUNT are three distinct identifiers.

Exported vs unexported

The case of the first letter carries a specific meaning in Go. An identifier that starts with an uppercase letter is exported — it is visible and accessible from other packages. One that starts with a lowercase letter is unexported — it is private to the package it is defined in.

package math

var internalState = 0  // unexported — only visible inside this package
var Pi = 3.14159       // exported — accessible as math.Pi from anywhere

This is not a convention — it is enforced by the compiler. There are no public or private keywords in Go. Capitalization is the entire access control mechanism.

The blank identifier

The underscore on its own — _ — is a special identifier called the blank identifier. It acts as a write-only discard slot: you can assign to it, but you can never read from it.

Its most common use is discarding values you do not need:

value, _ := strconv.Atoi("42") // discard the error

Go requires that every declared variable is used. The blank identifier lets you satisfy that requirement when a function returns multiple values and you only care about some of them.

Predeclared identifiers

Go comes with a set of identifiers that are always available in every program without any import. They are defined in the universe block — the outermost scope that wraps all Go code.

Unlike keywords, predeclared identifiers are not reserved. You can technically shadow them by declaring your own identifier with the same name. You almost certainly should not — doing so removes access to the original and creates confusing code.

Types

any bool byte comparable complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr

You have already seen most of these in the basic types article. any is an alias for interface{} — the type that accepts any value. error is an interface type used throughout Go for error handling. comparable is a constraint used in generics.

Constants

Three predeclared constants exist:

  • true and false — the only values of type bool
  • iota — the compile-time counter used inside const blocks

The zero value: nil

nil is the zero value for pointers, slices, maps, channels, functions, and interfaces. It is not a keyword — it is a predeclared identifier with no type of its own. Its type is determined by context.

var p *int       // p is nil
var s []string   // s is nil
var m map[string]int // m is nil

Built-in functions

Go provides a set of built-in functions that are always in scope:

FunctionPurpose
lenLength of a string, slice, map, array, or channel
capCapacity of a slice or channel
makeAllocate and initialize slices, maps, and channels
newAllocate zeroed memory for a type, return a pointer
appendAppend elements to a slice
copyCopy elements between slices
deleteRemove a key from a map
closeClose a channel
complexConstruct a complex number from real and imaginary parts
realExtract the real part of a complex number
imagExtract the imaginary part of a complex number
panicStop normal execution and begin unwinding the stack
recoverRegain control after a panic
printWrite to stderr (low-level, for debugging)
printlnWrite to stderr with a newline (low-level, for debugging)

print and println are not fmt.Print

The built-in print and println write to standard error and are intended for low-level debugging during bootstrap — before the runtime is fully initialized. For any real output, use the fmt package: fmt.Print, fmt.Println, fmt.Printf.

Keywords

Keywords are words that the Go language itself has claimed. They have fixed meanings built into the compiler and cannot be used as identifiers — you cannot name a variable func or a type for.

Go has exactly 25 keywords. This small number is deliberate — fewer keywords means a smaller language that is easier to learn and easier to read.

Declaration and types

These keywords introduce new entities into the program:

KeywordPurpose
varDeclare a variable
constDeclare a constant
typeDeclare a new type or type alias
funcDeclare a function or method
structDefine a composite type with named fields
interfaceDefine a set of method signatures
mapDeclare a map type
chanDeclare a channel type
packageDeclare the package a file belongs to
importImport packages

Control flow

These keywords control the order of execution:

KeywordPurpose
if / elseConditional branching
forThe only loop construct in Go
rangeIterate over a slice, map, string, or channel
switch / case / defaultMulti-branch conditional
breakExit a loop or switch
continueSkip to the next loop iteration
returnExit a function, optionally returning values
gotoJump to a labeled statement
fallthroughContinue into the next case in a switch

Concurrency and deferred execution

KeywordPurpose
goLaunch a goroutine
selectWait on multiple channel operations
deferSchedule a function call to run when the surrounding function returns

Go has no while

Go does not have a while keyword. The for loop covers all loop patterns: for {} is an infinite loop, for condition {} is a while loop, and for i := 0; i < n; i++ {} is a classic counted loop.