Page Content

Tutorials

What Are Go Decision Making Statements With Code Examples

Go Decision Making statements

Your program can evaluate certain criteria and then run multiple code paths depending on whether those conditions are met with decision-making statements, sometimes referred to as control structures or branching statements. Instead than just allowing programs to operate from start to finish, they allow them to make decisions.

The main decision-making statements in Go are switch and if.

if statement

A condition is evaluated by the if statement to see if it is true or false. Following the if statement, the code block is run if the condition is true. If not, the block is omitted.

Basic if Statement Example: To determine whether a student’s grade is passing, for instance:

package main
import "fmt"
func main() {
    grade := 70
    if grade >= 65 { // Condition: grade is greater than or equal to 65
        fmt.Println("Passing grade") // Clause: executed if condition is true
    }
}

Output

Passing grade
  • Since the grade in this instance is 70, which is greater than 65, the result will be a passing grade.
  • Since no alternative action is mentioned and the condition is false, there would be no output if the grade were 60.

if-else Statement

You can use an else statement to give an alternate action in the event that the if condition is false.

Example:

package main
import "fmt"
func main() {
    grade := 60
    if grade >= 65 {
        fmt.Println("Passing grade")
    } else { // Executed if the if condition is false
        fmt.Println("Failing grade")
    }
}

Output

Failing grade

Since the if condition (grade >= 65) is false when grade is 60, the else block runs and prints Failing grade.

if-else if-else Statement

Elsewhere if statements can be used to assess a range of values or more than two alternative outcomes. Only the first condition in an else if statement that evaluates to true will have its corresponding block run since conditions in these statements are tested top-down.

Example: Consider using numerical ranges to assign letter grades:

package main
import "fmt"
func main() {
    grade := 83
    if grade >= 90 {
        fmt.Println("A grade")
    } else if grade >= 80 { // Checked if the first condition is false
        fmt.Println("B grade")
    } else if grade >= 70 {
        fmt.Println("C grade")
    } else if grade >= 65 {
        fmt.Println("D grade")
    } else { // Catch-all for all other cases
        fmt.Println("Failing grade")
    }
}

Output

B grade

Grade >= 90 is a false initial condition for a grade of 83. No additional else if or then blocks are tested because the second condition (grade >= 80) is true, and a B grade is printed.

Nested if Statements

Put if statements inside other if or else blocks to check for secondary circumstances. This is known as nested if statements. This enables you to have several distinct layers of conditions in your code.

Example:

package main
import "fmt"
func main() {
    grade := 92
    if grade >= 65 { // Outer if statement: checks if passing
        fmt.Print("Passing grade of: ")
        if grade >= 90 { // Nested if statement: checks for 'A' range
            fmt.Println("A")
        } else if grade >= 80 {
            fmt.Println("B")
        } else if grade >= 70 {
            fmt.Println("C")
        } else if grade >= 65 {
            fmt.Println("D")
        }
    } else { // Outer else statement: handles failing grades
        fmt.Println("Failing grade")
    }
}

Output

Passing grade of: A

The outer if for grade 92 is true. Printing A indicates that the nested if (grade >= 90) is true. Failing grade would be printed and the nested statements would be completely skipped if the outer if was false (grade 60, for example).

switch statement

Long if-else if chains can be replaced with a switch statement, which is cleaner, particularly when comparing a single variable to a range of potential values.

Basic switch Statement: After the switch keyword, an expression (often a variable) and a string of case clauses enclosed in curly brackets make up a switch statement. In each case, the value of the expression is compared to the value or values. The code is run in that instance if they match. If none of the other case values match, a default case that executes might be added.

Example: Selecting ice cream preferences:

package main
import "fmt"
func main() {
    flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}
    for _, flav := range flavors {
        switch flav {
        case "strawberry":
            fmt.Println(flav, "is my favorite!")
        case "vanilla", "chocolate": // Multiple values can be listed in a single case
            fmt.Println(flav, "is great!")
        default: // Executed if no other case matches
            fmt.Println("I've never tried", flav, "before")
        }
    }
}

Output

chocolate is great!
vanilla is great!
strawberry is my favorite!
I've never tried banana before

This software cycles through a variety of flavours. It prints “strawberry is my favourite!” for the word “strawberry”. The words “vanilla” and “chocolate” print “_ is great!” The default scenario for “banana” is displayed, with the words “I’ve never tried banana before” printed.

In contrast to several other languages, switch statements in Go don’t “fall through” by default. Because case conditions are checked top-down, only one case block will run even if several case requirements are satisfied.

General switch Statement (with conditions): To enable each case to have its own Boolean condition, you can remove the expression that follows the switch keyword. This combines related conditionals into a group, much like a sequence of if-else if statements.

Example: A guessing game:

package main
import (
	"fmt"
	"math/rand"
	"time"
)
func main() {
	rand.Seed(time.Now().UnixNano())
	target := rand.Intn(100) // Random number between 0 and 99
	for {
		var guess int
		fmt.Print("Enter a guess: ")
		_, err := fmt.Scanf("%d", &guess)
		if err != nil {
			fmt.Println("Invalid guess: err:", err)
			continue
		}
		switch { // No expression after switch, cases contain conditions
		case guess > target:
			fmt.Println("Too high!")
		case guess < target:
			fmt.Println("Too low!")
		default: // This case handles when guess == target
			fmt.Println("You win!")
			return // Exits the function (and program)
		}
	}
}

Output

Enter a guess: 5
Too low!
Enter a guess: 19
Too low!
Enter a guess: 7
Too low!
Enter a guess: 2023
Too high!
Enter a guess: 

Depending on whether guess == target, this switch statement examines guess > target, guess < target, or falls through to default.

fallthrough Keyword: The fallthrough keyword can be used to specifically instruct a switch statement to execute the body of the case clause that follows the current one.

Example:

package main
import "fmt"
func main() {
    flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}
    for _, flav := range flavors {
        switch flav {
        case "strawberry":
            fmt.Println(flav, "is my favorite!")
            fallthrough // Executes the next case's body
        case "vanilla", "chocolate":
            fmt.Println(flav, "is great!")
        default:
            fmt.Println("I've never tried", flav, "before")
        }
    }
}

Output

chocolate is great!
vanilla is great!
strawberry is my favorite!
strawberry is great!
I've never tried banana before
  • “strawberry” will provide the following result: “strawberry is my favourite!” Strawberries are delicious!
  • Because of the fallthrough keyword, the code in the “vanilla” and “chocolate” cases also runs after the strawberry case.
  • Using fallthrough to reuse code is generally discouraged; for clarity, it is usually preferable to define a function using the common code.

switch with Interface and Data Types: The x.(type) syntax can also be used to distinguish between various interface variable data types in a switch statement.

Example:

package main
import "fmt"
type square struct {
    X float64
}
type circle struct {
    R float64
}
func tellInterface(x interface{}) {
    switch v := x.(type) { // Differentiates between data types of x
    case square:
        fmt.Println("This is a square!")
    case circle:
        fmt.Printf("%v is a circle!\n", v)
    default:
        fmt.Printf("Unknown type %T!\n", v)
    }
}
func main() {
    x := circle{R: 10}
    tellInterface(x)
    y := square{X: 4}
    tellInterface(y)
    tellInterface(10) // An integer
}

Output

{10} is a circle!
This is a square!
Unknown type int!

The interface x is left empty when using the tellInterface method. The switch v := x.The program can verify the underlying concrete type of x and run the appropriate case with the (type) statement. This is a square!, 10 is a circle!, and Unknown type int! will all be printed.

Common Principles for Decision Making

Boolean Values: If and switch statements’ conditions have to evaluate to a true or false Boolean value.

Logical Operators: By utilizing the logical operators && (AND), || (OR), and! (NOT), you can combine numerous conditions. Go employs && and || short-circuit logic.

Curly Braces: If, else, else if, and switch statements are followed by code blocks that are encapsulated in curly braces {}.

Variable Scope: Usually, variables declared inside an if or switch statement (using the short declaration :=) are scoped to the statement and any else if or else blocks that go with it.

Clarity: Selecting between switch and if-else if frequently boils down to readability and making your goal obvious to other developers.

You can also read What Is Mean By Go Variables, Constants With Code Examples

Agarapu Geetha
Agarapu Geetha
My name is Agarapu Geetha, a B.Com graduate with a strong passion for technology and innovation. I work as a content writer at Govindhtech, where I dedicate myself to exploring and publishing the latest updates in the world of tech.
Index