Chapter 4: Go Syntax
Go Syntax” means the complete set of rules defining how code must look: keywords, punctuation, how declarations work, control structures, operators, etc. Go’s syntax is famous for being:
- Very clean and minimal (no semicolons needed most times, fewer parentheses/braces than C++/Java)
- Readable (designed so teams can read each other’s code easily)
- Simple to parse (tools like gofmt, IDEs love it)
- C-like but cleaner (no header files, no classes/inheritance drama)
The official place to see the full, precise syntax is: https://go.dev/ref/spec → “The Go Programming Language Specification” (updated as of Jan 2026 for Go 1.26 changes)
But today I’ll teach it like a patient human teacher — not dry spec language, but with explanations, comparisons, common patterns, and lots of runnable examples.
We’ll cover the most important parts beginners care about (90% of daily coding), in logical order.
1. Basic File Structure (Every Go File Looks Like This)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Line 1: Must declare which package this file belongs to package main // "main" → this file can have func main() → becomes executable // Imports come next (standard library or third-party) import ( "fmt" // printing "time" // we'll use later ) // Optional: constants, types, variables at package level // Entry point — only one per executable package func main() { fmt.Println("Hello, Syntax from Hyderabad! 🇮🇳") } |
- No semicolons at end of lines (Go adds them automatically during compilation)
- Braces { } are mandatory even for single-line blocks
- go fmt or VS Code auto-formats everything — no style wars!
2. Comments (Simple & Clean)
|
0 1 2 3 4 5 6 7 8 9 10 11 |
// Single-line comment /* Multi-line comment Can span several lines */ |
No /** Javadoc */ style — keep it simple.
3. Variables & Declarations (Go Way vs Old Way)
Go has two main styles — use the short one most of the time!
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
func main() { // Classic style (like C/Java) — explicit type var name string = "Webliance" var age int = 25 var height float64 = 175.5 var isStudent bool = true // Short declaration (preferred in Go — type inferred!) city := "Hyderabad" // string temperature := 32 // int pi := 3.14159 // float64 learningGo := true // bool // Multiple at once x, y, z := 10, 20, 30 // Zero values (if you don't assign) var defaultInt int // → 0 var defaultString string // → "" var defaultBool bool // → false fmt.Printf("Name: %s, Age: %d, City: %s\n", name, age, city) } |
Key rules:
- := can only be used inside functions (short declaration)
- Variables must be used (no unused vars allowed — compiler error!)
- Types are static — can’t change later
4. Basic Types (Quick Overview)
| Type | Example literal | Zero value | Notes |
|---|---|---|---|
| int / int64 | 42, -10 | 0 | Platform-dependent size (usually 64-bit now) |
| float64 | 3.14, -0.001 | 0.0 | Main floating point type |
| bool | true, false | false | |
| string | “Hello”, raw string | “” | Immutable, UTF-8 |
| byte | byte(‘A’) | 0 | alias for uint8 |
| rune | ‘A’, ‘హ’ | 0 | alias for int32, represents Unicode code point |
5. Constants (Compile-time Only)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const Pi = 3.14159 // inferred float64 const MaxRetries = 5 // int // Multiple const ( Sunday = 0 Monday = 1 // ... ) |
No const inside functions usually — they’re package-level.
6. Control Structures (if, for, switch — No while!)
if (no parentheses around condition!)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
age := 25 if age >= 18 { fmt.Println("Adult") } else if age >= 13 { fmt.Println("Teen") } else { fmt.Println("Kid") } // With short init statement (very common) if n := 10; n > 5 { fmt.Println("n is big") } |
for (the only loop in Go — no while/do-while)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// Classic for for i := 0; i < 5; i++ { fmt.Println(i) } // Like while j := 0 for j < 3 { fmt.Println("j =", j) j++ } // Infinite (use break) for { fmt.Println("Looping...") break // escape } // Range over slice/array/map/string fruits := []string{"apple", "banana", "cherry"} for index, fruit := range fruits { fmt.Printf("%d: %s\n", index, fruit) } |
switch (very powerful — no fallthrough by default)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
day := "Monday" switch day { case "Monday", "Tuesday": fmt.Println("Work start") case "Saturday", "Sunday": fmt.Println("Weekend!") default: fmt.Println("Mid-week") } // Type switch (cool for interfaces) var i interface{} = 42 switch v := i.(type) { case int: fmt.Println("Integer:", v) case string: fmt.Println("String:", v) default: fmt.Println("Unknown type") } |
7. Arrays vs Slices (Most People Use Slices!)
Array — fixed size
|
0 1 2 3 4 5 6 7 |
var a [3]int = [3]int{1, 2, 3} // or short: a := [3]int{1, 2, 3} |
Slice — dynamic, most used
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
s := []int{10, 20, 30} // literal s = append(s, 40) // grows automatically // Make with capacity names := make([]string, 0, 10) // len=0, cap=10 // Slicing (like Python) subset := s[1:3] // [20, 30] |
8. Maps (Hash tables)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
m := make(map[string]int) m["apple"] = 5 m["banana"] = 3 value, exists := m["orange"] // exists = false if missing delete(m, "banana") for key, val := range m { fmt.Printf("%s → %d\n", key, val) } |
9. Functions (Multiple returns are normal!)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
func add(x int, y int) int { // long params return x + y } // Short params (same type) func subtract(x, y int) int { return x - y } // Multiple returns (idiomatic for errors) func divide(a, b float64) (float64, error) { if b == 0 { return 0, fmt.Errorf("division by zero") } return a / b, nil } // Named returns (auto-returned) func split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x return // "naked" return — returns named values } |
10. Pointers (Simple — no pointer arithmetic like C)
|
0 1 2 3 4 5 6 7 8 9 |
x := 42 p := &x // p points to x *p = 100 // change x via pointer fmt.Println(x) // → 100 |
No -> — use . even on pointers (p.Field works if p is pointer to struct).
Quick 2026 Update Notes
- Go 1.26 (Feb 2026) added new(expr) — you can do ptr := new(42) instead of x := 42; ptr := &x
- Generics (since 1.18) — type parameters: func Print[T any](v T) { … }
Your Mini Syntax Exercise
Fix this broken code (try mentally, then type it):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
package main import fmt func main x = 10 if x > 5 Println("big") } |
Correct version:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package main import "fmt" func main() { x := 10 if x > 5 { fmt.Println("big") } } |
Ready to practice more? Want deep dive on any part:
- Slices internals (append, copy, capacity)
- Struct + methods
- Interfaces
- Error handling patterns
- Defer/panic/recover
- Goroutines + channels syntax
Just name it — we’ll go deeper with examples.
Open VS Code, create syntax.go, and start typing — let’s build muscle memory! 💻🚀
Keep going, you’re doing fantastic! 🇮🇳
