Now that your development environment is set up, it's time to explore Go's language features and best practices. The guiding principle? Write code that clearly communicates your intentions. As we dive into Go's built-in types and variable declarations, you'll see how subtle differences from other languages can impact readability and functionality.

The Predeclared Types

Go comes with several built-in types, known as predeclared types. These include familiar options like booleans, integers, floats, and strings. While they may seem straightforward, transitioning developers often need to adjust to Go's idiomatic usage. Before examining each type, let's cover some universal concepts.

The Zero Value

Like many modern languages, Go assigns a default zero value to any declared but unassigned variable. This explicit zeroing eliminates bugs common in languages like C and C++. Each type's zero value will be discussed alongside its details.

Literals

Go literals represent explicitly specified numbers, characters, or strings. There are four common kinds (plus a rare fifth for complex numbers):

  • Integer literals: Base 10 by default, with prefixes for binary (0b), octal (0o), and hexadecimal (0x). Underscores improve readability (e.g., 1_234).
  • Floating-point literals: Include a decimal point or exponent (6.03e23). Hexadecimal floats use 0x and p for exponents.
  • Rune literals: Represent characters in single quotes, with various numeric escapes (e.g., '\u0061' for 'a').
  • String literals: Use double quotes for interpreted strings (processing escapes) or backticks for raw strings (no escapes).

Literals are untyped, defaulting to a type when context doesn't specify one.

Booleans

The bool type holds true or false, with a zero value of false.

Numeric Types

Go offers 12 numeric types across three categories:

Integer Types

Signed and unsigned integers range from 1 to 8 bytes (see table in original text). All have a zero value of 0.

Special Integer Types

  • byte: Alias for uint8.
  • int and uint: Platform-dependent (32 or 64 bits). Integer literals default to int.
  • rune and uintptr: For Unicode code points and pointer arithmetic, respectively.

Choosing an Integer

  1. Match external formats (e.g., network protocols).
  2. Use generics for library functions.
  3. Default to int otherwise.

Integer Operators

Standard arithmetic (+, -, *, /, %) and bitwise operations (<<, >>, &, |, ^). Division truncates toward zero.

Floating-Point Types

float32 and float64 follow IEEE 754. Prefer float64 for precision. Avoid floats for exact decimals (e.g., money).

Complex Types

complex64 and complex128 support complex numbers via the complex function. Rarely used outside niche applications.

Strings and Runes

Strings are immutable, Unicode-compatible, and support concatenation (+). The rune type (alias for int32) represents Unicode code points. Zero value is an empty string.

Explicit Type Conversion

Go requires manual conversion between types, even for similar numerics. For example:

var x int = 10
var y float64 = 30.2
sum := float64(x) + y // Explicit conversion

No non-boolean type can be converted to bool; use comparisons instead.

Literals Are Untyped

Literals adapt to compatible types but can't overflow variables (e.g., assigning 1000 to a byte errors).

Variable Declarations: var vs. :=

  • var for zero values, package-level vars, or explicit types.
  • := for type-inferred local variables (must declare at least one new var).

Constants

Declared with const, constants are immutable and computed at compile time. They can be typed or untyped (more flexible).

Naming Conventions

  • Use camelCase, not snake_case.
  • Short names in small scopes (e.g., i, k).
  • Descriptive names at package level.
  • Avoid underscores and Unicode look-alikes.

Unused Variables

Go enforces local variable usage (compile-time error if unused). Package-level vars and constants are exempt but discouraged.

Exercises

  1. Declare an integer i as 20, assign to float f, and print both.
  2. Create a constant assignable to int and float64, then print both.
  3. Assign max values to byte, int32, and uint64 vars, increment, and print.

Wrapping Up

You've now mastered Go's predeclared types, declarations, and idioms. Next, we'll explore composite types like slices and maps, and revisit strings and runes in depth.