Integer literals
Ah integer literals! Now we’re starting to get into the meat of the language.
Go lets us express integers in four bases. 10 (decimal) is by far the most common, followed by base 16 (hexidecimal). Base 8 (octal) and base 2 (binary) are also supported, but seen fairly rarely.
Here’s how the spec describes it:
An integer literal is a sequence of digits representing an integer constant. An optional prefix sets a non-decimal base:
0b
or0B
for binary,0
,0o
, or0O
for octal, and0x
or0X
for hexadecimal. A single0
is considered a decimal zero. In hexadecimal literals, lettersa
throughf
andA
throughF
represent values10
through15
.
The astute reader may wonder why octal supports three prefixes, 0
, 0o
and 0O
, whereas binary and hexidecimal each support only two (their upper- and lowercase- versions).
This is for historical reasons. Prior to the release of Go 1.13 in September 2019, there were no binary literals, and octal literals were indicated solely by the 0
prefix.
To make everything more consistent in Go 1.13, they added binary, with the respective 0b
and 0B
prefixes, and added the 0o
and 0O
prefixes for octal literals, to be consistent with the 0x
and 0X
prefixes already supported for hexidecimal literals.
These days, the plain 0
prefix should be considered obsolete, although it will continue to work indefinitely, if you’re using the standard gofmt
tool (and you should be!), it will reformat any octal literals with the old bare 0
prefix to use 0o
.
For readability, an underscore character
_
may appear after a base prefix or between successive digits; such underscores do not change the literal’s value.
At the same time that Binary literals and standard Ocatl prefixes were added, they added the option to include arbitrary undescores (_
) to literals. This should be used when it enhanches readability, such as to group by thousands when writing decimal literals.
int_lit = decimal_lit | binary_lit | octal_lit | hex_lit . decimal_lit = "0" | ( "1" … "9" ) [ [ "_" ] decimal_digits ] . binary_lit = "0" ( "b" | "B" ) [ "_" ] binary_digits . octal_lit = "0" [ "o" | "O" ] [ "_" ] octal_digits . hex_lit = "0" ( "x" | "X" ) [ "_" ] hex_digits . decimal_digits = decimal_digit { [ "_" ] decimal_digit } . binary_digits = binary_digit { [ "_" ] binary_digit } . octal_digits = octal_digit { [ "_" ] octal_digit } . hex_digits = hex_digit { [ "_" ] hex_digit } .
42 4_2 0600 0_600 0o600 0O600 // second character is capital letter 'O' 0xBadFace 0xBad_Face 0x_67_7a_2f_cc_40_c6 170141183460469231731687303715884105727 170_141183_460469_231731_687303_715884_105727 _42 // an identifier, not an integer literal 42_ // invalid: _ must separate successive digits 4__2 // invalid: only one _ at a time 0_xBadFace // invalid: _ must separate successive digits
Quotes from The Go Programming Language Specification, Version of June 29, 2022