Go
Variables, Types & Control Flow
Go is statically typed, exactly like C — every variable has one fixed type, known at compile time. What's different is how you get there: Go can often infer a variable's type from its initial value, removing a lot of the type-name repetition C requires.
- What it is
- Statically-typed variable declarations (
varor:=), Go's built-in types, andif/for/switchfor control flow. - Mental model
- Same rigid typing discipline as C, but the compiler is willing to figure out the type itself whenever it obviously can, so you don't have to write it twice.
- Key numbers
- Exactly one loop keyword (
for) covers every shape C needs three keywords for (for,while,do-while). - Reach for it when
- Any time you'd declare a variable or branch on a condition — this is Go's most-used syntax, used in literally every program.
Declaring variables: var and :=
var age int = 25 // explicit type, C-style order reversed (name THEN type)
var name string = "Ada"
var price float64 // no initializer — defaults to the type's "zero value" (0 here)
count := 10 // := infers the type from the value — count is an int, automatically
message := "Hello" // message is a string, automatically
:= is the idiomatic, far more common form inside functions — you only reach for the longer
var form when you need to declare a variable without immediately initializing it, or when
you're declaring it outside any function.
Go's built-in types
| Go type | Closest C equivalent | Notes |
|---|---|---|
int | int | Platform's natural word size (32 or 64 bits) — like C, size isn't fixed by the spec |
int32, int64 | int32_t, int64_t | Fixed-width, exactly like C's stdint.h types from Embedded C |
float64 | double | The default floating-point type in Go — used far more often than float32 |
string | char* / char array | A real, built-in type — not a convention layered on char arrays like C strings |
bool | _Bool / int | A genuine boolean type from the start — Go never had C's "0 is false" convention |
Every variable declared without an explicit initial value gets a well-defined zero value
(0 for numbers, "" for strings, false for booleans) — unlike a
plain C local variable, which starts as
uninitialized garbage.
if — no parentheses required
temperature := 85
if temperature > 90 {
fmt.Println("Too hot")
} else if temperature < 60 {
fmt.Println("Too cold")
} else {
fmt.Println("Comfortable")
}
Functionally identical to C's if/else if/else
— the only real difference is syntax: no parentheses around the condition, and the braces are mandatory
even for a single statement (removing an entire category of C bug from
C's Control Flow gotchas about a dangling if
with no braces).
for — Go's only loop keyword
Go has exactly one loop keyword, shaped to cover every case C needs three separate keywords for:
// C-style three-part for (like C's for loop)
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// condition-only (like C's while loop)
count := 0
for count < 5 {
fmt.Println(count)
count++
}
// no condition at all (like C's for (;;) or while (1))
for {
fmt.Println("forever, until a break")
break
}
All three are the same keyword, just with different parts omitted — see C's Loops for the three separate forms Go collapses into this one.
switch — no fall-through by default
day := 3
switch day {
case 1:
fmt.Println("Monday")
case 2:
fmt.Println("Tuesday")
case 3:
fmt.Println("Wednesday")
default:
fmt.Println("Some other day")
}
// Wednesday — and execution stops here automatically, no break needed
This is the single biggest behavioral difference from C's switch:
Go's cases do not fall through by default — each case implicitly breaks. Go still
supports intentional fall-through, but only with an explicit fallthrough keyword, inverting
C's "opt out of fall-through" into "opt in."
Real-world applications
- Request handling in web services —
if/switchon an HTTP method or status code is one of the most common patterns in Go server code. - Configuration parsing —
:=type inference keeps config-loading code compact, since the types are usually obvious from context. - Polling/retry loops — the condition-only
forform is Go's idiomatic replacement for a C-stylewhileloop, common in networked service code waiting on a resource.
Gotchas
- Forgetting that Go's
switchdoesn't fall through is a common early mistake coming from C — code that "should" fall through silently doesn't, unlessfallthroughis added explicitly. :=can only be used to declare a new variable — using it when the variable already exists in the same scope is a compile error; use plain=to reassign an existing variable's value.- Go's compiler rejects an unused variable outright (see Introduction to Go's gotchas) — a variable declared with
:=and never referenced again fails to compile, not just warns. - Comparing floating-point values with
==has exactly the same reliability problem in Go as in C — the underlying IEEE 754 representation issue doesn't go away just because the language changed.