Values, Constants & Numbers
Go deliberately made its basic values small and predictable — a handful of fixed-width integer types, read-only strings, constants driven by an iota counter. Because of that simplicity they are barely studied: "well, a number is a number, what is there to learn." That is precisely why they produce the quietest and most expensive bugs — the ones that do not fail at build time and surface only in production or in an interview.
There is mechanism under the simple syntax. An integer is a fixed bit layout with specific overflow behaviour, and the width of int depends on the platform and is fixed by the compiler, not chosen at runtime. An unsigned type does not go negative — it wraps around modulo 2^n. A string is an immutable sequence of bytes, and len(s) counts exactly those bytes, not characters. This topic takes values apart layer by layer — from how a single integer is built to the rules for the visibility of names in a package.
Topic map
- Signed and unsigned types — two's complement, non-negative
uint, and wrap-around modulo 2^n on overflow instead of an error. - Integer sizes — fixed widths of 8/16/32/64 bits and the platform-dependent
intwhose width is fixed by the implementation, not the runtime. - Integer range — how two's complement splits bits between the negative and positive halves and why the
int64maximum is 2^63−1. - Integer division — integer
/truncates toward zero, convert before dividing, and divide-by-zero panics. - Runes vs bytes —
len(s)counts bytes,utf8.RuneCountInStringcounts runes, andrangeover a string decodes runes. - Scope and visibility — nested scopes from block to universe and cross-package visibility by identifier case.
- switch and control flow —
switchwith no fall-through,fallthrough,switch true, the type switch, and labeled break in a loop.
Common Mistakes and Traps
| Mistake | Consequence |
|---|---|
Believing uint panics or saturates on overflow | Silent wrap-around modulo 2^n; an infinite loop or a wrong counter |
Subtracting a larger uint from a smaller one expecting a negative result | You get a huge positive number — there is no intermediate "minus" |
| Thinking a signed type stores the sign in a separate flag bit | Wrong two's-complement model; an error in the range calculation |
Treating int as always 32-bit or always 64-bit | Size mismatch between platforms; a corrupted binary format |
Taking the int64 maximum as 2^64−1 or 2^63 | That is the uint64 range or an off-by-one; the correct value is 2^63−1 |
Writing float64(a / b) instead of float64(a) / float64(b) | Division truncates in int BEFORE the cast — precision is lost |
| Dividing by zero without checking the slice length | sum / len(s) on an empty slice panics integer divide by zero |
Believing s[0] = 'R' is a runtime panic | It is a compile error — string does not support index assignment |
Treating len(s) as the number of characters | len counts bytes; a multi-byte UTF-8 character counts as two or more |
Forgetting that a line with _ also consumes an iota value | All following constants shift by one |
Confusing := in a nested block with assignment | It declares a NEW variable shadowing the outer one — an error or value is "lost" |
Expecting break in a switch inside a for to leave the loop | It leaves only the switch; the loop keeps spinning |
| Treating a struct copy as a reference | b := a copies ALL fields; mutating b is not visible in a |
| Mistaking struct embedding for inheritance | It is composition: no polymorphism, an own field simply shadows the embedded one |
Interview Relevance
Numbers and values are the warm-up of a Go interview, but they are exactly where the inattentive get filtered out. Interviewers ask not the syntax but the model of behaviour under it: when a type wraps, when division truncates, what len actually counts.
What interviewers check:
- The difference between signed and unsigned types — two's complement and wrap-around modulo 2^n.
- What integer widths Go provides and what determines the width of
int— the implementation and platform, not the runtime. - How to compute the range of
int64and why its maximum is 2^63−1, not 2^63 or 2^64−1. - What integer
/does and whyfloat64(a / b)loses precision. - Why
stringis immutable and what indexing a string returns — abyte, not a character. - How
len(s)differs from the rune count and howrangeover a string decodes runes. - How
iotacounts (including lines with_) and the rules of name visibility and shadowing in a package.
A typical wrong answer: "an unsigned counter will go negative when you subtract — it is just ordinary arithmetic." That opens the discussion that uint has no "minus": on overflow it wraps around modulo 2^n, and a for i := uint(...); i >= 0; i-- loop never terminates.