Chapter 3. Go Control Flow

Go borrows several of its control flow syntax from the C-family of languages. It supports all of the expected control structures, including if...else, switch, for loop, and even goto. Conspicuously absent, though, are while or do...while statements. The following topics in this chapter examine Go's control flow elements, some of which you may already be familiar with, and others that bring a new set of functionalities not found in other languages:

  • The if statement
  • The switch statement
  • The type Switch
  • The for statement

The if statement

The if statement, in Go, borrows its basic structural form from other C-like languages. The statement conditionally executes a code block when the Boolean expression that follows the if keyword evaluates to true, as illustrated in the following abbreviated program, which displays information about world currencies:

import "fmt" 
 
type Currency struct { 
  Name    string 
  Country string 
  Number  int 
} 
 
var CAD = Currency{ 
    Name: "Canadian Dollar",  
    Country: "Canada",  
    Number: 124} 
 
var FJD = Currency{ 
    Name: "Fiji Dollar",  
    Country: "Fiji",  
    Number: 242} 
 
var JMD = Currency{ 
    Name: "Jamaican Dollar",  
    Country: "Jamaica",  
    Number: 388} 
 
var USD = Currency{ 
    Name: "US Dollar",  
    Country: "USA",  
    Number: 840} 
 
func main() { 
  num0 := 242 
  if num0 > 100 || num0 < 900 { 
    fmt.Println("Currency: ", num0) 
    printCurr(num0) 
  } else { 
    fmt.Println("Currency unknown") 
  } 
 
  if num1 := 388; num1 > 100 || num1 < 900 { 
    fmt.Println("Currency:", num1) 
    printCurr(num1) 
  } 
} 
 
func printCurr(number int) { 
  if CAD.Number == number { 
    fmt.Printf("Found: %+v
", CAD) 
  } else if FJD.Number == number { 
    fmt.Printf("Found: %+v
", FJD) 
  } else if JMD.Number == number { 
    fmt.Printf("Found: %+v
", JMD) 
  } else if USD.Number == number { 
    fmt.Printf("Found: %+v
", USD) 
  } else { 
    fmt.Println("No currency found with number", number) 
  } 
} 

golang.fyi/ch03/ifstmt.go

The if statement in Go looks similar to other languages. However, it sheds a few syntactic rules, while enforcing new ones:

  • The parentheses around the test expression are not necessary. While the following if statement will compile, it is not idiomatic:
          if (num0 > 100 || num0 < 900) { 
            fmt.Println("Currency: ", num0) 
            printCurr(num0) 
          } 
    
  • Use the following instead:
          if num0 > 100 || num0 < 900 { 
            fmt.Println("Currency: ", num0) 
            printCurr(num0) 
          } 
    
  • The curly braces for the code block are always required. The following snippet will not compile:
          if num0 > 100 || num0 < 900 printCurr(num0) 
    
  • However, this will compile:
          if num0 > 100 || num0 < 900 {printCurr(num0)} 
    
  • It is idiomatic, however, to write the if statement on multiple lines (no matter how simple the statement block may be). This encourages good style and clarity. The following snippet will compile with no issues:
          if num0 > 100 || num0 < 900 {printCurr(num0)} 
    
  • However, the preferred idiomatic layout for the statement is to use multiple lines, as follows:
          if num0 > 100 || num0 < 900 { 
            printCurr(num0) 
          }
  • The if statement may include an optional else block, which is executed when the expression in the if block evaluates to false. The code in the else block must be wrapped in curly braces using multiple lines, as shown in the following snippet:
          if num0 > 100 || num0 < 900 { 
            fmt.Println("Currency: ", num0) 
            printCurr(num0) 
          } else { 
            fmt.Println("Currency unknown") 
          } 
    
  • The else keyword may be immediately followed by another if statement forming an if...else...if chain, as used in the function printCurr() from the source code listed earlier:
          if CAD.Number == number { 
            fmt.Printf("Found: %+v
    ", CAD) 
          } else if FJD.Number == number { 
            fmt.Printf("Found: %+v
    ", FJD) 
          } 
    

The if...else...if statement chain can grow as long as needed and may be terminated by an optional else statement to express all other untested conditions. Again, this is done in the printCurr() function, which tests four conditions using the if...else...if blocks. Lastly, it includes an else statement block to catch any other untested conditions:

func printCurr(number int) { 
  if CAD.Number == number { 
    fmt.Printf("Found: %+v
", CAD) 
  } else if FJD.Number == number { 
    fmt.Printf("Found: %+v
", FJD) 
  } else if JMD.Number == number { 
    fmt.Printf("Found: %+v
", JMD) 
  } else if USD.Number == number { 
    fmt.Printf("Found: %+v
", USD) 
  } else { 
    fmt.Println("No currency found with number", number) 
  } 
}

In Go, however, the idiomatic, and cleaner, way to write such a deep if...else...if code block is to use an expressionless switch statement. This is covered later, in the Switch statement section.

The if statement initialization

The if statement supports a composite syntax where the tested expression is preceded by an initialization statement. At runtime, the initialization is executed before the test expression is evaluated, as illustrated in this code snippet (from the program listed earlier):

if num1 := 388; num1 > 100 || num1 < 900 { 
  fmt.Println("Currency:", num1) 
  printCurr(num1) 
}  

The initialization statement follows normal variable declaration and initialization rules. The scope of the initialized variables is bound to the if statement block, beyond which they become unreachable. This is a commonly used idiom in Go and is supported in other flow control constructs covered in this chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.109.8