Variables, Constants, Control Flow & Enums in Go 🚦
Go was engineered for simplicity, readability, and minimalism. Unlike languages with dozens of keyword variations, Go has only 25 keywords and a single loop construct (for).
1. Values, Variables & Constants
Basic Values
Go has familiar primitive types: strings, integers (int, int64), floats (float64), and booleans (bool):
package main
import "fmt"
func main() {
// String concatenation
fmt.Println("go" + "lang")
// Arithmetic
fmt.Println("7.0/3.0 =", 7.0/3.0)
// Booleans
fmt.Println(true && false)
fmt.Println(!true)
}Declaring Variables (var vs :=)
In Go, variables are initialized with either var or the short declaration :=:
package main
import "fmt"
func main() {
// 1. var with explicit type
var name string = "Alice"
// 2. var with type inference
var age = 30
// 3. Short declaration operator ':=' (Inside functions only!)
city := "San Francisco"
// 4. Zero values: Variables declared without a value get initialized to ZERO
var count int // 0
var price float64 // 0.0
var active bool // false
var token string // "" (empty string)
fmt.Println(name, age, city, count, price, active, token)
}Constants & Untyped Literals
Constants are declared using the const keyword. In Go, numeric constants are high-precision untyped values until assigned to a variable:
const Pi = 3.14159265359
const TimeoutSeconds = 30
// Typed constant
const MaxBufferSize int = 10242. Enums Using iota
Go does not have a dedicated enum keyword. Instead, idiomatic Go defines custom types and assigns sequential integer values using iota:
package main
import "fmt"
type ServerState int
// iota starts at 0 and increments by 1 for each line in the const block
const (
StateIdle ServerState = iota // 0
StateConnected // 1
StateError // 2
StateRetired // 3
)
// Implementing fmt.Stringer gives clean text representation
func (s ServerState) String() string {
switch s {
case StateIdle:
return "idle"
case StateConnected:
return "connected"
case StateError:
return "error"
case StateRetired:
return "retired"
default:
return "unknown"
}
}
func main() {
current := StateConnected
fmt.Printf("Server state: %s (numeric: %d)\n", current, current)
// Output: Server state: connected (numeric: 1)
}3. The for Loop: Go’s Only Loop Construct
Go has no while or do-while loops. The for keyword handles all looping scenarios:
package main
import "fmt"
func main() {
// 1. Classic 3-component loop
for i := 0; i < 3; i++ {
fmt.Print(i, " ")
}
fmt.Println()
// 2. While-style single condition loop
count := 1
for count <= 3 {
fmt.Print(count, " ")
count++
}
fmt.Println()
// 3. Infinite loop with break and continue
for {
if count > 5 {
break // exit loop
}
count++
}
// 4. Go 1.22+ integer range loop:
for i := range 3 {
fmt.Print(i, " ") // prints: 0 1 2
}
fmt.Println()
}4. if / else with Short Statement Initialization
In Go, conditional if statements do not need parentheses. Furthermore, Go allows executing a short statement before the condition:
package main
import (
"fmt"
"math/rand"
)
func main() {
// Idiomatic pattern: execute a function, initialize a variable, and test it immediately!
// 'num' only exists within the scope of this if/else block!
if num := rand.Intn(100); num > 50 {
fmt.Printf("High number: %d\n", num)
} else if num == 50 {
fmt.Println("Exactly fifty!")
} else {
fmt.Printf("Low number: %d\n", num)
}
// 'num' is out of scope here!
}5. switch: Clean Branching Without break
In Go, switch cases break automatically (no manual break needed; use fallthrough if you explicitly want fallthrough):
package main
import (
"fmt"
"time"
)
func main() {
// 1. Multiple expressions in a single case
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println("It's the weekend! 🎉")
default:
fmt.Println("It's a weekday 💻")
}
// 2. Tagless switch (alternative to chained if/else)
hour := time.Now().Hour()
switch {
case hour < 12:
fmt.Println("Good morning!")
case hour < 17:
fmt.Println("Good afternoon!")
default:
fmt.Println("Good evening!")
}
}Across the Wiki
- Slices & Maps in Go — Looping over collections with
for i, v := range. - Functions, Pointers & Strings — Function syntax and multiple return values.
- Type Assertions & Type Switches — Switching on dynamic interface types.