Chapter 17: Integer
Integer data types.
In Go, integers are very explicit — unlike Python (one int type) or JavaScript (everything becomes Number), Go gives you precise control over size and signedness. This is intentional: Go was designed for systems programming, performance-critical code, protocols, embedded systems, crypto → you often need to know exactly how many bits you’re using.
Let’s go through everything like we’re sitting together with laptop open — theory, table, declaration patterns, real examples, common traps, and when to choose which type.
1. Two Big Families of Integers in Go
| Family | Can be negative? | Types available | Zero value | Most common in 2025–2026 code |
|---|---|---|---|---|
| Signed | Yes | int, int8, int16, int32, int64 | 0 | int (general purpose) |
| Unsigned | No (≥ 0 only) | uint, uint8, uint16, uint32, uint64, uintptr | 0 | uint (sizes, indices), uint8 (byte) |
2. Detailed Table — All Integer Types (2026 reality on 64-bit systems)
| Type | Bits | Signed? | Min value | Max value | Typical use case | Recommendation / Notes |
|---|---|---|---|---|---|---|
| int | 32 or 64 (usually 64 now) | Yes | –2⁶³ or –2³¹ | 2⁶³–1 or 2³¹–1 | General counters, lengths, loop indices | Default choice for most code |
| int8 | 8 | Yes | –128 | 127 | Small signed values, old hardware, packed data | Rare unless memory tight |
| int16 | 16 | Yes | –32,768 | 32,767 | Audio samples, some network protocols | Uncommon today |
| int32 | 32 | Yes | –2,147,483,648 | 2,147,483,647 | Unicode code points (rune alias) | Use when you need exactly 32 bits |
| int64 | 64 | Yes | –9.22×10¹⁸ | 9.22×10¹⁸ | Timestamps (UnixNano), large IDs, crypto | Very common for big numbers |
| uint | 32 or 64 (usually 64) | No | 0 | 2⁶⁴–1 or 2³²–1 | Array lengths, buffer sizes, bit fields | Use when value cannot be negative |
| uint8 | 8 | No | 0 | 255 | byte alias — raw bytes, ASCII, colors | Extremely common |
| uint16 | 16 | No | 0 | 65,535 | Ports, RGB565 colors, some file formats | Occasional |
| uint32 | 32 | No | 0 | 4,294,967,295 | IPv4 addresses, CRC32, hashes | Common in networking |
| uint64 | 64 | No | 0 | 18,446,744,073,709,551,615 | File sizes, nanosecond timestamps, nonces | Very common |
| uintptr | same as uint (platform) | No | 0 | platform max | Low-level pointer arithmetic (rare) | Almost never in normal code |
3. Declaration & Literal Examples (Copy-Paste & Run)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package main import "fmt" func main() { // Most common — short declaration + int (platform size, usually 64-bit) count := 42 // int population := 1_400_000_000 // int — underscores allowed since Go 1.13 // Explicit size smallSigned int8 = -100 mediumSigned int16 = -30_000 largeSigned int64 = 9_223_372_036_854_775_807 // max int64 // Unsigned family byteValue uint8 = 255 // same as byte port uint16 = 8080 fileSize uint64 = 18_446_744_073_709_551_615 // max uint64 // Zero values var uninitInt int var uninitUint8 uint8 fmt.Printf("count: %d (type %T)\n", count, count) // 42 (int) fmt.Printf("smallSigned: %d\n", smallSigned) // -100 fmt.Printf("byteValue (uint8): %d\n", byteValue) // 255 fmt.Printf("fileSize (uint64): %d\n", fileSize) fmt.Printf("uninitInt: %d uninitUint8: %d ← zero values\n", uninitInt, uninitUint8) } |
4. Important Rules & Behaviors
- Literals without suffix are untyped until assigned → they can fit into any integer type that can hold them
|
0 1 2 3 4 5 6 7 8 9 |
var a int8 = 100 // ok var b int16 = 100 // ok var c uint8 = 100 // ok // var d int8 = 200 // compile error — 200 > 127 |
- No implicit conversion between signed ↔ unsigned or different sizes
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var i int = 42 var u uint = 100 // i = u // ERROR — cannot use uint value as int // u = i // ERROR // You must convert explicitly u = uint(i) // ok — but can lose sign or overflow i = int(u) // ok — but can overflow or change meaning |
- Overflow is wrap-around (two’s complement) — no panic (unlike some languages)
|
0 1 2 3 4 5 6 7 8 |
var x uint8 = 255 x++ // wraps to 0 fmt.Println(x) // 0 |
5. Common Real-World Patterns (2026 style)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// 1. Loop index / length → always int or uint (never int8 etc.) for i := 0; i < len(slice); i++ { ... } // 2. Byte / raw data → uint8 aka byte data := []byte{0x48, 0x65, 0x6C, 0x6C, 0x6F} // "Hello" // 3. Large counters / IDs / timestamps → int64 or uint64 unixNano := time.Now().UnixNano() // int64 // 4. Bit flags → usually uint or uint32/64 const ( FlagRead uint32 = 1 << 0 FlagWrite uint32 = 1 << 1 FlagExecute uint32 = 1 << 2 ) |
6. Your Quick Practice Exercise
Create integers.go and try:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package main import "fmt" func main() { var temperature int8 = 35 var usersOnline uint = 1_234_567 var fileSizeGB uint64 = 2_147_483_648 // larger than max int32 fmt.Printf("Temperature: %d °C (int8)\n", temperature) fmt.Printf("Users: %d (uint)\n", usersOnline) fmt.Printf("File size: %d GB (uint64)\n", fileSizeGB) // Try overflow (carefully) var small uint8 = 250 small += 10 fmt.Printf("250 + 10 = %d ← wrapped!\n", small) // 4 } |
Change values, try to assign negative to uint → see compile error.
Questions now?
- When exactly to prefer int64 over int?
- How to safely convert between signed/unsigned?
- Bitwise operations on integers?
- Or next: floating-point types? strings? or composite types again?
Keep typing and running these — integers are the workhorse of almost every program. You’re doing great! 💪🇮🇳 Let’s keep going! 🚀
