Program Structure & Looping Constructs
21 Sep 2025
Program Structure & Looping Constructs
Structuring Programs in Go
Go encourages a modular approach to building programs.
Functions provide process abstraction, making code easier to understand, test, and maintain.
- A Go program consists of one or more packages.
- Execution starts in the
main
package, specifically in themain()
function. - Functions can be user-defined or come from the standard library.
Functions in Go
- Functions must be declared (with their signature) before use.
- They cannot be nested inside other functions.
- They can be defined across multiple files as long as they belong to the same package.
Example:
package main
import (
"fmt"
)
func getNum() int { // function definition
var number int
fmt.Print("Please enter a number: ")
fmt.Scan(&number)
return number
}
func main() { // program entry point
a := getNum() // function call
b := getNum()
if a > b {
fmt.Printf("%d is the largest\n", a)
} else {
fmt.Printf("%d is the largest\n", b)
}
}
Function Arguments
Values are passed into functions via argument lists.
func add(a int, b int) int {
return a + b
}
func main() {
result := add(4, 5)
fmt.Println(result) // 9
}
- Formal parameters specify types and names of arguments.
- Actual arguments must match in type and number when calling.
Go uses positional arguments—the order matters.
Function Declarations (Prototypes)
Unlike C++, Go does not require forward declarations or prototypes.
Functions can be defined in any order within a package, as long as they’re in the same package scope.
Multiple Return Values
Go functions can return multiple values, which is a common idiom.
func minMax(a, b int) (int, int) {
if a > b {
return b, a
}
return a, b
}
func main() {
low, high := minMax(4, 9)
fmt.Println(low, high) // 4 9
}
Variadic Functions
Functions can accept a variable number of arguments.
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
func main() {
fmt.Println(sum(1, 2, 3, 4)) // 10
}
Passing Values
Go supports pass-by-value semantics for all arguments:
- Primitives (int, float, bool, string) are copied.
- Slices, maps, channels, interfaces, and functions are reference-like types; the reference is copied, but underlying data is shared.
Example: Pass by Value
func swap(a, b int) {
a, b = b, a
}
func main() {
x, y := 5, 6
swap(x, y)
fmt.Println(x, y) // 5 6 (unchanged)
}
Using Pointers for Mutation
To modify the caller’s variables, use pointers:
func swap(a, b *int) {
*a, *b = *b, *a
}
func main() {
x, y := 5, 6
swap(&x, &y)
fmt.Println(x, y) // 6 5
}
Go has no &
or *
operators for references like C++ references, but pointers provide similar behavior.
Scope
Scope determines visibility of variables.
- Package-level variables are visible to all files in the same package.
- Function-level variables are local to that function.
- Block-level variables are local to a
{ ... }
block.
var global int // package scope
func main() {
x := 5 // function scope
{
y := 10 // block scope
fmt.Println(x, y, global)
}
// fmt.Println(y) // ❌ not visible here
}
Control Flow: Loops
Go has only one loop keyword: for
.
It can act like while
, do-while
, or a traditional for
loop.
While-Style Loop
i := 10
for i > 0 {
fmt.Println(i)
i--
}
Infinite Loop
for {
fmt.Println("running")
break
}
For with Multiple Conditions
for a, b := 0, 0; (a < 1 || a > 10) || (b > 10 || b < 1); {
fmt.Print("enter two numbers between 1 and 10: ")
fmt.Scan(&a, &b)
}
Go does not have a
do-while
loop.
Use afor
loop withbreak
to simulate one:
var a, b int
for {
fmt.Print("enter two numbers between 1 and 10: ")
fmt.Scan(&a, &b)
if (a >= 1 && a <= 10) && (b >= 1 && b <= 10) {
break
}
}
Basic for
Loop
The classic loop has three components: initialization, condition, and post-update.
for i := 0; i < 10; i++ {
fmt.Println(i)
}
- Initialization: runs once before the loop starts (
i := 0
). - Condition: checked before each iteration (
i < 10
). - Post-update: executed after each iteration (
i++
). - The loop variable
i
is scoped inside the loop.
Any of these sections can be omitted:
for ; condition ; { ... } // like a while loop
for { ... } // infinite loop
While-Style Loop
Go does not have a while
keyword.
Use a for
with only a condition:
i := 10
for i > 0 {
fmt.Println(i)
i--
}
Do-While Equivalent
Go has no direct do…while
.
Simulate it with an infinite loop and a break
:
for {
fmt.Print("Enter a number (0 to quit): ")
var n int
fmt.Scan(&n)
if n == 0 {
break
}
}
Range Loop
Use range
to iterate over arrays, slices, maps, strings, or channels.
nums := []int{2, 4, 6, 8}
for i, v := range nums {
fmt.Printf("Index %d → Value %d\n", i, v)
}
i
is the index (or key for maps).v
is the value (or rune when iterating over strings).- Use
_
to ignore an index or value:
for _, v := range nums {
fmt.Println(v)
}
range
automatically handles UTF-8 in strings:
for _, r := range "Golang" {
fmt.Printf("%c ", r)
}
Break and Continue
break
exits the nearest loop.continue
skips to the next iteration.
for i := 0; i < 10; i++ {
if i == 3 { continue } // skip 3
if i == 7 { break } // stop entirely
fmt.Println(i)
}
If Statement
Go uses a straightforward if
syntax:
if x > 10 {
fmt.Println("x is big")
} else if x == 10 {
fmt.Println("x is exactly 10")
} else {
fmt.Println("x is small")
}
Short Declarations in If
You can declare a variable that exists only inside the if
and else
blocks:
if n := len(name); n > 5 {
fmt.Println("Long name")
} else {
fmt.Println("Short name")
}
Ternary Operator
Go does not have ?:
.
Use a regular if
or write a helper function:
// Instead of a > b ? a : b
max := a
if b > a {
max = b
}
Switch Statement
Go’s switch
is more flexible than C++:
switch day {
case 0:
fmt.Println("Monday")
case 1:
fmt.Println("Tuesday")
case 5, 6:
fmt.Println("Weekend")
default:
fmt.Println("Unknown")
}
- No need for
break
: cases don’t fall through by default. - Use
fallthrough
to intentionally continue:
switch x {
case 1:
fmt.Println("one")
fallthrough
case 2:
fmt.Println("one or two")
}
Switch without a value
Acts like chained if
statements:
switch {
case x < 0:
fmt.Println("negative")
case x == 0:
fmt.Println("zero")
default:
fmt.Println("positive")
}
Infinite Loops
A loop that runs forever:
for {
// do work
}
Combine with break
or return
to exit.