CodeRigor

FREE LESSON

Go values, types & zero values

Read Go declarations, distinguish typed arithmetic, and make conversions before information is lost.

Go is a compiled, statically typed language with local type inference. If you come from Python, n := 4 is concise declaration syntax, not permission to put a string into n later. If you come from C++, the type follows the declared name: var n int. Declarations inside functions may use := when at least one name on the left is new in that scope. Assignment to an existing name uses =. Package-level declarations use var, const, type or func rather than :=.

The runnable examples are complete programs. package main names an executable package; its main function is the entry point. Library exercises use the same package name for the test harness, but the harness supplies the entry point. Imports name dependencies explicitly, and an unused import or local variable is a compilation error. Formatting with gofmt is an ordinary part of the workflow. Braces belong to the control-flow syntax, not indentation alone.

Zero is a value, not missing initialization

A declared variable starts at its type's zero value: zero for numbers, false for bool and the empty string for string. That gives a predictable starting state; it does not prove that zero is valid for your application. A count of zero may be valid while a denominator of zero needs an explicit policy. Go has no general truthiness conversion: an if condition must be bool. Write n != 0 when that is the condition you mean.

A short declaration still has a fixed type
start / 4
The literal is checked, a type is inferred, and later assignments must respect it.
A short declaration still has a fixed type
The literal is checked, a type is inferred, and later assignments must respect it.

Preserve information at the arithmetic boundary

Integer division truncates toward zero. When both operands are ints, 1 / 4 has already become zero before any outer float64 conversion runs. Convert the operands first when the mathematical result can contain a fraction. The build uses a bounded integer domain, so the exercises focus on that boundary rather than architecture-dependent int overflow. A conversion is a request with its own rules, not an automatic proof that information was preserved.

Go
package main
import "fmt"
func main() {
    var ready bool
    total := 125
    fmt.Println(ready, total/60, total%60)
    fmt.Println(float64(1)/float64(4), float64(1/4))
}

The output is false 2 5, followed by 0.25 0. Quotient and remainder answer different questions. For nonnegative seconds, recombining minutes*60+seconds must reproduce the original value, and the remainder stays below sixty.

Quotient and remainder
start / 2
125 seconds is two full groups of 60 plus five remaining seconds.
Quotient and remainder
125 seconds is two full groups of 60 plus five remaining seconds.

Practice the contract

Predict zero values before running the snippet. Change 125 to 59, 60 and 61 and explain both outputs. In the build, implement SplitSeconds and Ratio, including the stated invalid-input policy. Keep the returned validity bool separate from the numeric zero value. The bug hunts distinguish a wrong operator from a conversion performed too late; the fill asks you to preserve the fraction.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Watch the opening language comparison and static typing examples. The 2013 lecture predates modules and generics; use current documentation and the native exercises for tooling.