One place for hosting & domains

      Statements

      How To Write Switch Statements in Go


      Introduction

      Conditional statements give programmers the ability to direct their programs to take some action if a condition is true and another action if the condition is false. Frequently, we want to compare some variable against multiple possible values, taking different actions in each circumstance. It’s possible to make this work using if statements alone. Writing software, however, is not only about making things work but also communicating your intention to your future self and other developers. switch is an alternative conditional statement useful for communicating actions taken by your Go programs when presented with different options.

      Everything we can write with the switch statement can also be written with if statements. In this tutorial, we’ll look at a few examples of what the switch statement can do, the if statements it replaces, and where it’s most appropriately applied.

      Structure of Switch Statements

      Switch is commonly used to describe the actions taken by a program when a variable is assigned specific values. The following example demonstrates how we would accomplish this using if statements:

      package main
      
      import "fmt"
      
      func main() {
          flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}
      
          for _, flav := range flavors {
              if flav == "strawberry" {
                  fmt.Println(flav, "is my favorite!")
                  continue
              }
      
              if flav == "vanilla" {
                  fmt.Println(flav, "is great!")
                  continue
              }
      
              if flav == "chocolate" {
                  fmt.Println(flav, "is great!")
                  continue
              }
      
              fmt.Println("I've never tried", flav, "before")
          }
      }
      

      This will generate the following output:

      Output

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

      Within main, we define a slice of ice-cream flavors. We then use a for loop to iterate through them. We use three if statements to print out different messages indicating preferences for different ice-cream flavors. Each if statement must use the continue statement to stop execution of the for loop so that the default message at the end is not printed for the preferred ice-cream flavors.

      As we add new ice-cream preferences, we have to keep adding if statements to handle the new cases. Duplicated messages, as in the case of "vanilla" and "chocolate", must have duplicated if statements. To future readers of our code (ourselves included), the repetitive nature of the if statements obscures the important part of what they are doing—comparing the variable against multiple values and taking different actions. Also, our fallback message is set apart from the conditionals, making it appear unrelated. The switch statement can help us organize this logic better.

      The switch statement begins with the switch keyword and is followed, in its most basic form, with some variable to perform comparisons against. This is followed by a pair of curly braces ({}) where multiple case clauses can appear. Case clauses describe the actions your Go program should take when the variable provided to the switch statement equals the value referenced by the case clause. The following example converts the previous example to use a switch instead of multiple if statements:

      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":
                  fmt.Println(flav, "is great!")
              default:
                  fmt.Println("I've never tried", flav, "before")
              }
          }
      }
      

      The output is the same as before:

      Output

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

      We’ve once again defined a slice of ice-cream flavors in main and used the range statement to iterate over each flavor. This time, however, we’ve used a switch statement that will examine the flav variable. We use two case clauses to indicate preferences. We no longer need continue statements as only one case clause will be executed by the switch statement. We’re also able to combine the duplicated logic of the "chocolate" and "vanilla" conditionals by separating each with a comma in the declaration of the case clause. The default clause serves as our catch-all clause. It will run for any flavors that we haven’t accounted for in the body of the switch statement. In this case, "banana" will cause default to execute, printing the message I've never tried banana before.

      This simplified form of switch statements addresses the most common use for them: comparing a variable against multiple alternatives. It also provides conveniences for us where we want to take the same action for multiple different values and some other action when none of the listed conditions are met by using the provided default keyword.

      When this simplified form of switch proves too limiting, we can use a more general form of switch statement.

      General Switch Statements

      switch statements are useful for grouping collections of more complicated conditionals to show that they are somehow related. This is most commonly used when comparing some variable against a range of values, rather than specific values as in the earlier example. The following example implements a guessing game using if statements that could benefit from a switch statement:

      package main
      
      import (
          "fmt"
          "math/rand"
          "time"
      )
      
      func main() {
          rand.Seed(time.Now().UnixNano())
          target := rand.Intn(100)
      
          for {
              var guess int
              fmt.Print("Enter a guess: ")
              _, err := fmt.Scanf("%d", &guess)
              if err != nil {
                  fmt.Println("Invalid guess: err:", err)
                  continue
              }
      
              if guess > target {
                  fmt.Println("Too high!")
                  continue
              }
      
              if guess < target {
                  fmt.Println("Too low!")
                  continue
              }
      
              fmt.Println("You win!")
              break
          }
      }
      

      The output will vary depending on the random number selected and how well you play the game. Here is the output from one example session:

      Output

      Enter a guess: 10 Too low! Enter a guess: 15 Too low! Enter a guess: 18 Too high! Enter a guess: 17 You win!

      Our guessing game needs a random number to compare guesses against, so we use the rand.Intn function from the math/rand package. To make sure we get different values for target each time we play the game, we use rand.Seed to randomize the random number generator based on the current time. The argument 100 to rand.Intn will give us a number in the range 0–100. We then use a for loop to begin collecting guesses from the player.

      The fmt.Scanf function gives us a means to read user input into a variable of our choosing. It takes a format string verb that converts the user’s input into the type we expect. %d here means we expect an int, and we pass the address of the guess variable so that fmt.Scanf is able to set that variable. After handling any parsing errors we then use two if statements to compare the user’s guess to the target value. The string that they return, along with bool, controls the message displayed to the player and whether the game will exit.

      These if statements obscure the fact that the range of values that the variable is being compared against are all related in some way. It can also be difficult, at a glance, to tell if we missed some part of the range. The next example refactors the previous example to use a switch statement instead:

      package main
      
      import (
          "fmt"
          "math/rand"
      )
      
      func main() {
          target := rand.Intn(100)
      
          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 {
              case guess > target:
                  fmt.Println("Too high!")
              case guess < target:
                  fmt.Println("Too low!")
              default:
                  fmt.Println("You win!")
                  return
              }
          }
      }
      

      This will generate output similar to the following:

      Output

      Enter a guess: 25 Too low! Enter a guess: 28 Too high! Enter a guess: 27 You win!

      In this version of the guessing game, we’ve replaced the block of if statements with a switch statement. We omit the expression argument to switch because we are only interested in using switch to collect conditionals together. Each case clause contains a different expression comparing guess against target. Similar to the first time we replaced if statements with switch, we no longer need continue statements since only one case clause will be executed. Finally, the default clause handles the case where guess == target since we have covered all other possible values with the other two case clauses.

      In the examples that we’ve seen so far, exactly one case statement will be executed. Occasionally, you may wish to combine the behaviors of multiple case clauses. switch statements provide another keyword for achieving this behavior.

      Fallthrough

      Sometimes you will want to reuse the code that another case clause contains. In these cases, it’s possible to ask Go to run the body of the next case clause listed using the fallthrough keyword. This next example modifies our earlier ice cream flavor example to more accurately reflect our enthusiasm for strawberry ice cream:

      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
              case "vanilla", "chocolate":
                  fmt.Println(flav, "is great!")
              default:
                  fmt.Println("I've never tried", flav, "before")
              }
          }
      }
      

      We will see this output:

      Output

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

      As we’ve seen previously, we define a slice of string to represent flavors and iterate through this using a for loop. The switch statement here is identical to the one we’ve seen before, but with the addition of the fallthrough keyword at the end of the case clause for "strawberry". This will cause Go to run the body of case "strawberry":, first printing out the string strawberry is my favorite!. When it encounters fallthrough it will run the body of the next case clause. This will cause the body of case "vanilla", "chocolate": to run, printing strawberry is great!.

      The fallthrough keyword is not used often by Go developers. Usually, the code reuse realized by using fallthrough can be better obtained by defining a function with the common code. For these reasons, using fallthrough is generally discouraged.

      Conclusion

      switch statements help us convey to other developers reading our code that a set of comparisons are somehow related to each other. They make it much easier to add different behavior when a new case is added in the future and make it possible to ensure that anything we forgot is handled properly as well with default clauses. The next time you find yourself writing multiple if statements that all involve the same variable, try rewriting it with a switch statement—you’ll find it easier to rework when it comes time to consider some other alternative value.

      If you’d like to learn more about the Go programming language, check out the entire How To Code in Go series.



      Source link

      Using Break and Continue Statements When Working with Loops in Go


      Introduction

      Using for loops in Go allow you to automate and repeat tasks in an efficient manner.

      Learning how to control the operation and flow of loops will allow for customized logic in your program. You can control your loops with the break and continue statements.

      Break Statement

      In Go, the break statement terminates execution of the current loop. A break is almost always paired with a conditional if statement.

      Let’s look at an example that uses the break statement in a for loop:

      break.go

      package main
      
      import "fmt"
      
      func main() {
          for i := 0; i < 10; i++ {
              if i == 5 {
                  fmt.Println("Breaking out of loop")
                  break // break here
              }
              fmt.Println("The value of i is", i)
          }
          fmt.Println("Exiting program")
      }
      

      This small program creates a for loop that will iterate while i is less than 10.

      Within the for loop, there is an if statement. The if statement tests the condition of i to see if the value is less than 5. If the value of i is not equal to 5, the loop continues and prints out the value of i. If the value of i is equal to 5, the loop will execute the break statement, print that it is Breaking out of loop, and stop executing the loop. At the end of the program we print out Exiting program to signify that we have exited the loop.

      When we run this code, our output will be the following:

      Output

      The value of i is 0 The value of i is 1 The value of i is 2 The value of i is 3 The value of i is 4 Breaking out of loop Exiting program

      This shows that once the integer i is evaluated as equivalent to 5, the loop breaks, as the program is told to do so with the break statement.

      Nested Loops

      It is important to remember that the break statement will only stop the execution of the inner most loop it is called in. If you have a nested set of loops, you will need a break for each loop if desired.

      nested.go

      package main
      
      import "fmt"
      
      func main() {
          for outer := 0; outer < 5; outer++ {
              if outer == 3 {
                  fmt.Println("Breaking out of outer loop")
                  break // break here
              }
              fmt.Println("The value of outer is", outer)
              for inner := 0; inner < 5; inner++ {
                  if inner == 2 {
                      fmt.Println("Breaking out of inner loop")
                      break // break here
                  }
                  fmt.Println("The value of inner is", inner)
              }
          }
          fmt.Println("Exiting program")
      }
      

      In this program, we have two loops. While both loops iterate 5 times, each has a conditional if statement with a break statement. The outer loop will break if the value of outer equals 3. The inner loop will break if the value of inner is 2.

      If we run the program, we can see the output:

      Output

      The value of outer is 0 The value of inner is 0 The value of inner is 1 Breaking out of inner loop The value of outer is 1 The value of inner is 0 The value of inner is 1 Breaking out of inner loop The value of outer is 2 The value of inner is 0 The value of inner is 1 Breaking out of inner loop Breaking out of outer loop Exiting program

      Notice that each time the inner loop breaks, the outer loop does not break. This is because break will only break the inner most loop it is called from.

      We have seen how using break will stop the execution of a loop. Next, let’s look at how we can continue the iteration of a loop.

      Continue Statement

      The continue statement is used when you want to skip the remaining portion of the loop, and return to the top of the loop and continue a new iteration.

      As with the break statement, the continue statement is commonly used with a conditional if statement.

      Using the same for loop program as in the preceding Break Statement section, we’ll use a continue statement rather than a break statement:

      continue.go

      package main
      
      import "fmt"
      
      func main() {
          for i := 0; i < 10; i++ {
              if i == 5 {
                  fmt.Println("Continuing loop")
                  continue // break here
              }
              fmt.Println("The value of i is", i)
          }
          fmt.Println("Exiting program")
      }
      

      The difference in using the continue statement rather than a break statement is that our code will continue despite the disruption when the variable i is evaluated as equivalent to 5. Let’s look at our output:

      Output

      The value of i is 0 The value of i is 1 The value of i is 2 The value of i is 3 The value of i is 4 Continuing loop The value of i is 6 The value of i is 7 The value of i is 8 The value of i is 9 Exiting program

      Here we see that the line The value of i is 5 never occurs in the output, but the loop continues after that point to print lines for the numbers 6-10 before leaving the loop.

      You can use the continue statement to avoid deeply nested conditional code, or to optimize a loop by eliminating frequently occurring cases that you would like to reject.

      The continue statement causes a program to skip certain factors that come up within a loop, but then continue through the rest of the loop.

      Conclusion

      The break and continue statements in Go will allow you to use for loops more effectively in your code.



      Source link

      How To Write Conditional Statements in Go


      Introduction

      Conditional statements are part of every programming language. With conditional statements, we can have code that sometimes runs and at other times does not run, depending on the conditions of the program at that time.

      When we fully execute each statement of a program, we are not asking the program to evaluate specific conditions. By using conditional statements, programs can determine whether certain conditions are being met and then be told what to do next.

      Let’s look at some examples where we would use conditional statements:

      • If the student receives over 65% on her test, report that her grade passes; if not, report that her grade fails.
      • If he has money in his account, calculate interest; if he doesn’t, charge a penalty fee.
      • If they buy 10 oranges or more, calculate a discount of 5%; if they buy fewer, then don’t.

      Through evaluating conditions and assigning code to run based on whether or not those conditions are met, we are writing conditional code.

      This tutorial will take you through writing conditional statements in the Go programming language.

      If Statements

      We will start with the if statement, which will evaluate whether a statement is true or false, and run code only in the case that the statement is true.

      In a plain text editor, open a file and write the following code:

      grade.go

      package main
      
      import "fmt"
      
      func main() {
          grade := 70
      
          if grade >= 65 {
              fmt.Println("Passing grade")
          }
      }
      

      With this code, we have the variable grade and are giving it the integer value of 70. We are then using the if statement to evaluate whether or not the variable grade is greater than or equal ( >= ) to 65. If it does meet this condition, we are telling the program to print out the string Passing grade.

      Save the program as grade.go and run it in a local programming environment from a terminal window with the command go run grade.go.

      In this case, the grade of 70 does meet the condition of being greater than or equal to 65, so you will receive the following output once you run the program:

      Output

      Passing grade

      Let’s now change the result of this program by changing the value of the grade variable to 60:

      grade.go

      package main
      
      import "fmt"
      
      func main() {
          grade := 60
      
          if grade >= 65 {
              fmt.Println("Passing grade")
          }
      }
      

      When we save and run this code, we will receive no output because the condition was not met and we did not tell the program to execute another statement.

      To give one more example, let us calculate whether a bank account balance is below 0. Let’s create a file called account.go and write the following program:

      account.go

      package main
      
      import "fmt"
      
      func main() {
          balance := -5
      
          if balance < 0 {
              fmt.Println("Balance is below 0, add funds now or you will be charged a penalty.")
          }
      }
      

      When we run the program with go run account.go, we’ll receive the following output:

      Output

      Balance is below 0, add funds now or you will be charged a penalty.

      In the program we initialized the variable balance with the value of -5, which is less than 0. Since the balance met the condition of the if statement (balance < 0), once we save and run the code, we will receive the string output. Again, if we change the balance to 0 or a positive number, we will receive no output.

      Else Statements

      It is likely that we will want the program to do something even when an if statement evaluates to false. In our grade example, we will want output whether the grade is passing or failing.

      To do this, we will add an else statement to the grade condition above that is constructed like this:

      grade.go

      package main
      
      import "fmt"
      
      func main() {
          grade := 60
      
          if grade >= 65 {
              fmt.Println("Passing grade")
          } else {
              fmt.Println("Failing grade")
          }
      }
      

      Since the grade variable has the value of 60, the if statement evaluates as false, so the program will not print out Passing grade. The else statement that follows tells the program to do something anyway.

      When we save and run the program, we’ll receive the following output:

      Output

      Failing grade

      If we then rewrite the program to give the grade a value of 65 or higher, we will instead receive the output Passing grade.

      To add an else statement to the bank account example, we rewrite the code like this:

      account.go

      package main
      
      import "fmt"
      
      func main() {
          balance := 522
      
          if balance < 0 {
              fmt.Println("Balance is below 0, add funds now or you will be charged a penalty.")
          } else {
              fmt.Println("Your balance is 0 or above.")
          }
      }
      

      Output

      Your balance is 0 or above.

      Here, we changed the balance variable value to a positive number so that the else statement will print. To get the first if statement to print, we can rewrite the value to a negative number.

      By combining an if statement with an else statement, you are constructing a two-part conditional statement that will tell the computer to execute certain code whether or not the if condition is met.

      Else if Statements

      So far, we have presented a Boolean option for conditional statements, with each if statement evaluating to either true or false. In many cases, we will want a program that evaluates more than two possible outcomes. For this, we will use an else if statement, which is written in Go as else if. The else if or else if statement looks like the if statement and will evaluate another condition.

      In the bank account program, we may want to have three discrete outputs for three different situations:

      • The balance is below 0
      • The balance is equal to 0
      • The balance is above 0

      The else if statement will be placed between the if statement and the else statement as follows:

      account.go

      package main
      
      import "fmt"
      
      func main() {
          balance := 522
      
          if balance < 0 {
              fmt.Println("Balance is below 0, add funds now or you will be charged a penalty.")
          } else if balance == 0 {
              fmt.Println("Balance is equal to 0, add funds soon.")
          } else {
              fmt.Println("Your balance is 0 or above.")
          }
      }
      

      Now, there are three possible outputs that can occur once we run the program:

      • If the variable balance is equal to 0 we will receive the output from the else if statement (Balance is equal to 0, add funds soon.)
      • If the variable balance is set to a positive number, we will receive the output from the else statement (Your balance is 0 or above.).
      • If the variable balance is set to a negative number, the output will be the string from the if statement (Balance is below 0, add funds now or you will be charged a penalty).

      What if we want to have more than three possibilities, though? We can do this by writing more than one else if statement into our code.

      In the grade.go program, let’s rewrite the code so that there are a few letter grades corresponding to ranges of numerical grades:

      • 90 or above is equivalent to an A grade
      • 80-89 is equivalent to a B grade
      • 70-79 is equivalent to a C grade
      • 65-69 is equivalent to a D grade
      • 64 or below is equivalent to an F grade

      To run this code, we will need one if statement, three else if statements, and an else statement that will handle all failing cases.

      Let’s rewrite the code from the preceding example to have strings that print out each of the letter grades. We can keep our else statement the same.

      grade.go

      package main
      
      import "fmt"
      
      func main() {
          grade := 60
      
          if grade >= 90 {
              fmt.Println("A grade")
          } else if grade >= 80 {
              fmt.Println("B grade")
          } else if grade >= 70 {
              fmt.Println("C grade")
          } else if grade >= 65 {
              fmt.Println("D grade")
          } else {
              fmt.Println("Failing grade")
          }
      }
      

      Since else if statements will evaluate in order, we can keep our statements pretty basic. This program is completing the following steps:

      1. If the grade is greater than 90, the program will print A grade, if the grade is less than 90, the program will continue to the next statement…

      2. If the grade is greater than or equal to 80, the program will print B grade, if the grade is 79 or less, the program will continue to the next statement…

      3. If the grade is greater than or equal to 70, the program will print C grade, if the grade is 69 or less, the program will continue to the next statement…

      4. If the grade is greater than or equal to 65, the program will print D grade, if the grade is 64 or less, the program will continue to the next statement…

      5. The program will print Failing grade because all of the above conditions were not met.

      Nested If Statements

      Once you are feeling comfortable with the if, else if, and else statements, you can move on to nested conditional statements. We can use nested if statements for situations where we want to check for a secondary condition if the first condition executes as true. For this, we can have an if-else statement inside of another if-else statement. Let’s look at the syntax of a nested if statement:

      if statement1 { // outer if statement
          fmt.Println("true")
      
          if nested_statement { // nested if statement
              fmt.Println("yes")
          } else { // nested else statement
              fmt.Println("no")
          }
      
      } else { // outer else statement
          fmt.Println("false")
      }
      

      A few possible outputs can result from this code:

      • If statement1 evaluates to true, the program will then evaluate whether the nested_statement also evaluates to true. If both cases are true, the output will be:

      Output

      true yes
      • If, however, statement1 evaluates to true, but nested_statement evaluates to false, then the output will be:

      Output

      true no
      • And if statement1 evaluates to false, the nested if-else statement will not run, so the else statement will run alone, and the output will be:

      Output

      false

      We can also have multiple if statements nested throughout our code:

      if statement1 { // outer if
          fmt.Println("hello world")
      
          if nested_statement1 { // first nested if
              fmt.Println("yes")
      
          } else if nested_statement2 { // first nested else if
              fmt.Println("maybe")
      
          } else { // first nested else
              fmt.Println("no")
          }
      
      } else if statement2 { // outer else if
          fmt.Println("hello galaxy")
      
          if nested_statement3 { // second nested if
              fmt.Println("yes")
          } else if nested_statement4 { // second nested else if
              fmt.Println("maybe")
          } else { // second nested else
              fmt.Println("no")
          }
      
      } else { // outer else
          statement("hello universe")
      }
      

      In this code, there is a nested if statement inside each if statement in addition to the else if statement. This will allow for more options within each condition.

      Let’s look at an example of nested if statements with our grade.go program. We can check for whether a grade is passing first (greater than or equal to 65%), then evaluate which letter grade the numerical grade should be equivalent to. If the grade is not passing, though, we do not need to run through the letter grades, and instead can have the program report that the grade is failing. Our modified code with the nested if statement will look like this:

      grade.go

      
      package main
      
      import "fmt"
      
      func main() {
          grade := 92
          if grade >= 65 {
              fmt.Print("Passing grade of: ")
      
              if grade >= 90 {
                  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 {
              fmt.Println("Failing grade")
          }
      }
      

      If we run the code with the variable grade set to the integer value 92, the first condition is met, and the program will print out Passing grade of:. Next, it will check to see if the grade is greater than or equal to 90, and since this condition is also met, it will print out A.

      If we run the code with the grade variable set to 60, then the first condition is not met, so the program will skip the nested if statements and move down to the else statement, with the program printing out Failing grade.

      We can of course add even more options to this, and use a second layer of nested if statements. Perhaps we will want to evaluate for grades of A+, A and A- separately. We can do so by first checking if the grade is passing, then checking to see if the grade is 90 or above, then checking to see if the grade is over 96 for an A+:

      grade.go

      …
      if grade >= 65 {
          fmt.Print("Passing grade of: ")
      
          if grade >= 90 {
              if grade > 96 {
                  fmt.Println("A+")
      
              } else if grade > 93 && grade <= 96 {
                  fmt.Println("A")
      
              } else {
                  fmt.Println("A-")
              }
      …
      

      In this code, for a grade variable set to 96, the program will run the following:

      1. Check if the grade is greater than or equal to 65 (true)
      2. Print out Passing grade of:
      3. Check if the grade is greater than or equal to 90 (true)
      4. Check if the grade is greater than 96 (false)
      5. Check if the grade is greater than 93 and also less than or equal to 96 (true)
      6. Print A
      7. Leave these nested conditional statements and continue with remaining code

      The output of the program for a grade of 96 therefore looks like this:

      Output

      Passing grade of: A

      Nested if statements can provide the opportunity to add several specific levels of conditions to your code.

      Conclusion

      By using conditional statements like the if statement, you will have greater control over what your program executes. Conditional statements tell the program to evaluate whether a certain condition is being met. If the condition is met it will execute specific code, but if it is not met the program will continue to move down to other code.

      To continue practicing conditional statements, try using different operators to gain more familiarity with conditional statements.



      Source link