AV
HomeAboutProjectBlog

© 2026 Ave syah Shina. All rights reserved.

  1. Home
  2. Blog
  3. 03 — Data Types — Integers, Floats, Booleans, and Runes

03 — Data Types — Integers, Floats, Booleans, and Runes

August 13, 20268 min read
Download as Markdown

"A number is a number" was my first Go assumption, and the compiler disagreed. The model that made it stick: Go is statically typed, which means every variable's type is fixed at compile time; the language offers a deliberate menu of fixed-size numeric types rather than one abstract "number"; and conversion between any two types — even closely related ones like int and int64 — is always explicit. [1] Static typing is not ceremony; it is the compiler catching int + float64 before it ever runs.

The whole menu at a glance

Signed ints Unsigned ints Floats & complex Text & truth int8 int16 int32 int64 uint8 uint16 uint32 uint64 float32 float64 complex64 complex128 bool string rune (int32) int and uint are platform-dependent — 32 bits on 32-bit CPUs, 64 on 64-bit. byte is an alias for uint8; rune is an alias for int32.

Integers — signed and unsigned

Go refuses to pretend integers are one thing. There are signed types (int8 through int64) that hold positive and negative values, and unsigned types (uint8 through uint64) that hold only non-negative values but with roughly double the positive range for the same bit width [2]. The bare int and uint are platform-dependent — 32-bit on a 32-bit CPU, 64-bit on a 64-bit one — which is why the advice is to use int for general counting and the explicit sizes only when memory layout or a wire protocol demands it.

Two aliases matter: byte is uint8, and rune is int32. They exist to signal intent — a []byte says "raw bytes," a []rune says "Unicode code points" — even though they compile to the same underlying type.

Floating point and complex

Floating point comes in float32 (single precision) and float64 (double precision, and the default for any literal like 3.14) [3]. Both follow IEEE 754, which means the usual caveat applies: floats cannot represent most decimal fractions exactly, so 0.1 + 0.2 != 0.3. For money or any value that must be exact, do not use floats — reach for an integer number of cents, a decimal library, or math/big. Floats are for measurements, graphics, and statistics where a tiny rounding error is acceptable.

Go also ships built-in complex numbers — complex64 and complex128 — with complex(), real(), imag(), and abs() helpers, plus literals like 3+4i [4]. Most backend code never touches them. They exist because Go was designed partly for systems and scientific work where signal processing and complex arithmetic show up, and baking them in keeps that code from reaching for a third-party library.

Booleans

bool is the simplest type: it holds true or false, its zero value is false, and it is what every comparison (==, !=, <) and logical operator (&&, ||, !) produces [5]. There is no notion of truthiness — you cannot write if someInt, the way you can in some languages. The condition must be a bool, full stop. That removes a whole category of "I forgot this value was an int, not a boolean" bugs.

Runes — Go's answer to "what is a character"

This is the type that confused me longest, because Go does not have a char type. A rune is an int32 that represents a Unicode code point — a single character in the Unicode standard, whether that is A, 中, or an emoji [6]. Single quotes denote a rune literal: 'A', '中'.

The subtlety — covered more in the strings notes — is that a Go string is a sequence of _bytes_, not runes. A multi-byte UTF-8 character like 中 occupies 3 bytes in a string. Indexing s[0] gives you the first _byte_, not the first _rune_. To walk a string by character, you use a for range loop, which decodes runes as it goes, or convert to []rune(s) for indexed access. The rune type is what lets Go handle internationalized text correctly, and ignoring the byte-vs-rune distinction is the most common source of broken string handling.

Explicit type conversion

The rule that shapes how all these types interact: Go has no implicit conversion. Even int and int64, which feel like the same thing, must be converted explicitly [7]:

var a int = 5
var b int64 = int64(a) // required — you cannot assign a to b directly
var c int32 = 10
total := a + int(c) // must convert c to int before adding

The syntax is Type(value) — the target type wrapping the value like a function call. This feels verbose coming from languages with automatic widening, but it eliminates an entire class of silent truncation and sign bugs. You can never accidentally lose precision without having written the conversion yourself. The compiler forces you to acknowledge every type boundary, which is exactly the point of static typing.

Reading the docs

The companion habit that made the type menu usable is go doc. Running go doc on a package, type, or function in the terminal prints the documentation extracted from comments in the source [8]:

go doc fmt.Println
go doc time.Duration

It is faster than switching to a browser and works offline. The same comments render on pkg.go.dev, but the terminal form is the one I reach for constantly while coding.

How I use this

The practical takeaways are three small rules. Default to int for counters and float64 for measurements; reach for the sized types (int64, uint32) only when a struct layout, a binary protocol, or an ID scheme requires it. Never store money in a float — use integer cents or a decimal type. And the moment a string operation starts dealing with characters, switch ways of thinking to runes: a for range loop or a []rune conversion, never raw byte indexing. The explicit-conversion rule does the rest of the work — every type boundary is a deliberate line I wrote, so there are no surprises in the math.

References

[1] The Go Authors, "Go Tour: Basic types," go.dev, 2024. [Online]. Available: https://go.dev/tour/basics/11

[2] Golang Docs, "Integers in Golang," 2024. [Online]. Available: https://golangdocs.com/integers-in-golang

[3] Golang Docs, "Floating point numbers in Golang," 2024. [Online]. Available: https://golangdocs.com/floating-point-numbers-in-golang

[4] Golang Docs, "Complex numbers in Golang," 2024. [Online]. Available: https://golangdocs.com/complex-numbers-in-golang

[5] Golang Docs, "Booleans in Golang," 2024. [Online]. Available: https://golangdocs.com/booleans-in-golang

[6] The Go Authors, "Strings, bytes, runes and characters in Go," The Go Blog, 2013. [Online]. Available: https://go.dev/blog/strings

[7] The Go Authors, "Go Tour: Type conversion," go.dev, 2024. [Online]. Available: https://go.dev/tour/basics/13

[8] N. Gautam, "A Guide to Effective Go Documentation," Medium, 2024. [Online]. Available: https://nirdoshgautam.medium.com/a-guide-to-effective-go-documentation-952f346d073f

Knowledge check · Question 1 of 5

What is `byte` an alias for in Go?

Comments

Leave a Comment

You must be signed in to comment

0 Comments

No comments yet. Be the first to comment!