tezvyn:

Primitive Scalars: Go vs Rust

AI-drafted, machine-checkedintermediate

Go's int grows with the architecture; Rust fixes sizes like i32 at compile time. Use Go's int for loops and Rust's i32 for counters, but both require explicit casts to mix. Assuming Go's int is 64-bit breaks 32-bit builds, and Rust's as truncates silently.

WHY IT EXISTS: Processors only understand fixed register widths, but programmers want portable code. Go hides this by providing int and uint that match the native word size, reducing decision fatigue. Rust exposes the hardware truth by making every scalar width explicit, preventing assumptions about memory layout from leaking across platforms.

THE MENTAL MODEL: Think of Go's scalars as defaults that just work on whatever machine compiles them. int is big enough to count memory on the local CPU, and conversions between numeric types are explicit but constants are flexible. Rust's scalars are precision tools: i32 is exactly four bytes everywhere, and the compiler treats mixing a u16 with an i32 as a type error rather than a silent conversion.

HOW IT WORKS: Go offers bool, int, uint, uintptr, and explicit widths like int8 through int64, uint8 through uint64, plus float32, float64, and complex numbers. int and uint are either 32 or 64 bits depending on the architecture. Rust offers bool, char, i8 through i128, u8 through u128, isize, usize, f32, and f64. isize and usize match the pointer width, but idiomatic Rust avoids them for general math. Go allows untyped constants to morph into whatever width fits, while Rust demands every literal have a known type or a suffix like 42u32.

WHEN TO USE IT: Use Go's int for indexing, counters, and slice lengths where the platform word is natural. Use Go's fixed-width types only when you need guaranteed layout for wire formats or C interop. In Rust, use i32 as the default integer, u8 for raw bytes, and usize exclusively for indexing and collection lengths. Use f64 in both languages unless you are optimizing for memory or GPU bandwidth.

WHEN NOT TO USE IT: Do not store Go's int in a database column or binary protocol if the width must be stable across 32-bit and 64-bit builds, because its size changes silently. Do not use Rust's as keyword for numeric conversions when correctness matters, because it truncates and wraps without panic; prefer TryFrom or checked arithmetic instead. Avoid Rust's isize for file sizes or network counts, because it can be 32 bits on some targets.

ONE CANONICAL EXAMPLE: Imagine writing a binary file header that starts with a 32-bit magic number and a 16-bit version. In Go, you must use uint32 and uint16 fields in your struct; if you used int, a 64-bit build would write eight bytes for the first field and corrupt the format. In Rust, you naturally define the struct with u32 and u16 fields, and the compiler guarantees the layout matches your intent on every target without hidden platform variation.

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.