03 - Making Decisions

📋 Jump to Takeaways

Programs that always do the same thing aren't very useful. Real programs react. "If the password is wrong, show an error." "If the score is above 90, print an A." That's what if statements do. They let your program choose what to do based on conditions.

Comparing Values

Before you can make decisions, you need to compare things:

10 == 10  // true  (equal)
10 != 5   // true  (not equal)
10 > 5    // true  (greater than)
10 < 5    // false (less than)
10 >= 10  // true  (greater or equal)
10 <= 9   // false (less or equal)

These work on strings too:

"go" == "go"    // true
"go" == "Go"    // false (case matters)
"abc" < "abd"   // true  (alphabetical order)

Every comparison produces a bool: true or false.

if / else

if runs a block of code only when a condition is true:

score := 85

if score >= 70 {
	fmt.Println("You passed!") // You passed!
}

Add else for what happens when the condition is false:

score := 50

if score >= 70 {
	fmt.Println("You passed!")
} else {
	fmt.Println("Try again.") // Try again.
}

Chain conditions with else if:

score := 85

if score >= 90 {
	fmt.Println("Grade: A")
} else if score >= 80 {
	fmt.Println("Grade: B") // Grade: B
} else if score >= 70 {
	fmt.Println("Grade: C")
} else {
	fmt.Println("Grade: F")
}

Go checks conditions top to bottom and runs the first one that's true. The rest are skipped.

Boolean Logic

Sometimes you need to combine conditions:

&&  // AND: both must be true
||  // OR: at least one must be true
!   // NOT: flips true to false, false to true
age := 25
hasID := true

if age >= 18 && hasID {
	fmt.Println("Entry allowed.") // this prints
}

if age < 18 || !hasID {
	fmt.Println("Entry denied.")
}

&& is strict, both sides must be true. || is lenient, one side is enough.

switch

When you're comparing one value against many options, switch is cleaner than a chain of if/else if:

day := "Tuesday"

switch day {
case "Monday":
	fmt.Println("Start of the week.")
case "Tuesday":
	fmt.Println("Second day.") // Second day.
case "Friday":
	fmt.Println("Almost weekend!")
default:
	fmt.Println("Just another day.")
}

default runs when nothing else matches. It's optional but good practice.

Go's switch doesn't fall through by default. Each case runs its block and exits the switch. No break needed.

switch without a value lets you use boolean expressions in each case:

score := 85

switch {
case score >= 90:
	fmt.Println("A")
case score >= 80:
	fmt.Println("B") // B
default:
	fmt.Println("C or below")
}

Reading User Input

To make decisions based on what the user types, you need to read input:

var choice string
fmt.Print("Enter your name: ")
fmt.Scan(&choice)
fmt.Println("Hello,", choice)

fmt.Scan(&choice) reads one word from the keyboard and stores it in choice. The & means "put the value here." Don't worry about why the & is needed yet, just know that fmt.Scan requires it.

Key Takeaways

  • Comparison operators (==, !=, <, >, <=, >=) produce bool values
  • if / else if / else runs code based on conditions
  • && (AND), || (OR), ! (NOT) combine boolean conditions
  • switch is cleaner than long if/else if chains
  • Go's switch doesn't fall through. Each case exits the switch automatically
  • switch without a value lets you use boolean expressions in each case
  • fmt.Scan(&variable) reads one word of input from the keyboard
  • Conditions are checked top to bottom. The first true branch runs, the rest are skipped

🚀 Ready to run?

Complete runnable examples for this lesson.

📝 Ready to test your knowledge?

Answer the quiz below to mark this lesson complete.

© 2026 ByteLearn.dev. Free courses for developers. · Privacy