"Switch" statements in GO
Tags: go, programming
Published: 2021-01-07 19:08:17

Switch statements are an important concept in programming and they are used for conditional execution. Switch statements in GO behave a little different as compared to other programming languages. So, in this blog we are going to understand switch statements in GO with the help of meaningful examples.
### Getting Started
Let's look at the following example
```go
package main
import "fmt"
func main() {
	fruit := "Orange"
	switch fruit {
	case "Apple":
		fmt.Printf("%v is a nice fruit\n", fruit)
	case "Mango":
		// We can have multiple lines of code inside case
		out := fmt.Sprintf("%v is a nice fruit", fruit)
		fmt.Println(out)
	case "Guava":
		// By default there's NO fall through
		fmt.Printf("%v is a nice fruit\n", fruit)
	case "Orange":
		fmt.Printf("%v is a nice fruit\n", fruit)
	default:
		fmt.Println("Unrecognized fruit")
	}
}
```
Can you guess the output of the above code snippet? If you've used switch statements in other programming languages you probably guessed the following
```
Mango is a nice fruit
Mango is a nice fruit
Mango is a nice fruit
Unrecognized fruit
```
But that's not the case with GO, here in switch statements we don't have fall through by default (_fall through basically means executing all cases that come after the matching case_). In GO only the statements within the matching case gets executed, so the output is simply `Mango is a nice fruit`.

**NOTE:** `switch expression == case expression` must be a valid comparison, so the code below would give an error.
```go
package main
import "fmt"
func main() {
	num := "Two"
	switch num {
	case 2:
		fmt.Printf("Num is 2")
	default:
		fmt.Println("Num is not 2")
	}
}
```
### Using `fallthrough`
What if we want to fall through, well for that we need to explicitly specify this by using the `fallthrough` keyword. So, the code below gives that output that we guessed earlier.
```go
package main
import "fmt"
func main() {
	fruit := "Mango"
	switch fruit {
	case "Apple":
		fmt.Printf("%v is a nice fruit\n", fruit)
	case "Mango":
		out := fmt.Sprintf("%v is a nice fruit", fruit)
		fmt.Println(out)
		fallthrough
	case "Guava":
		fmt.Printf("%v is a nice fruit\n", fruit)
		fallthrough
	case "Orange":
		fmt.Printf("%v is a nice fruit\n", fruit)
		fallthrough
	default:
		fmt.Println("Unrecognized fruit")
	}
}
```
Note that we had to specify `fallthrough` multiple times to get the desired output, so fallthrough just executes the next case block (_irrespective of whether that block is true or false_) and not all the subsequent case blocks.
Also, as in other programming languages the `default` case is optional and is triggered when no other cases match (_the default case can be placed anywhere not necessarily at the very bottom_)
### Multiple Case Expressions
We can also have multiple case expressions separated by commas. If any of the case expressions match the switch expression, then the statements associated with that particular case are executed.
```go
package main
import "fmt"
func main() {
        fruit := "Onion";
	switch fruit {
	case "Apple", "Mango", "Guava":
		fmt.Println("Fruit")
	case "Potato", "Cabbage", "Onion":
		fmt.Println("Vegetable")
	default:
		fmt.Println("What is it?")
	}
}
// OUTPUT
// Vegetable
```
Till now I have only used literal values in switch and case expressions, but that's not the only possibility. Take a look at the following example
```go
package main
import "fmt"
func main() {
	fruit := "Onion"
	switch fruit + "s" {
	case "Apple" + "s", "Mango" + "es":
		fmt.Println("Fruits")
	case "Cabbage" + "s", "Onion" + "s":
		fmt.Println("Vegetables")
	default:
		fmt.Println("What is it?")
	}
}
// OUTPUT
// Vegetables
```
### Switch Initializer
We can also have a **switch initializer** as shown below:
```go
package main
import "fmt"
func main() {
	switch fruit := "Onion"; fruit{
	case "Apple", "Mango":
		fmt.Println("Fruit")
	case "Cabbage", "Onion":
		fmt.Println("Vegetable")
	default:
		fmt.Println("What is it?")
	}
}
```
Now the variable `fruit` is only available within the switch block, not within the entire `main` function.
### Expressionless Switch
If we don't specify an expression to switch then it defaults to the boolean value `true` and now the program looks for case expressions that evaluate to `true` and this is similar to an `if-else-if-else` chain.
```go
package main
import "fmt"
func main() {
	for i := 1; i <= 30; i++ {
		switch {
		case i%15 == 0:
			fmt.Println(i, "Baz")
		case i%3 == 0:
			fmt.Println(i, "Foo")
		case i%5 == 0:
			fmt.Println(i, "Bar")
		default:
			// default is optional
			fmt.Println(i)
		}
	}
}
``` 
## Type Switches
A type switch compares types rather than values. It is otherwise similar to an expression switch. Take a look at the following example.
```go
package main
import "fmt"
func main() {
	var num interface{} = "Hello, World"
	switch num.(type) {
	case int:
		fmt.Printf("num is of type int")
	case bool:
		fmt.Printf("num is of type bool")
	case string:
		fmt.Printf("num is of type string")
	}
}
// OUTPUT
// num is of type string
```
So, I hope we now have a clear understanding of how switch statements work in GO.