Go like any other languages has the "if" statement. This is using a conditional expression to create a fork in the program. When the conditional value is true the next statement or a group of statements is executed, otherwise is not executed and skipped.
Conditional Execution
Example of decision with a single block.
//file conditional_branch.go
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func main() {
fmt.Println(sqrt(2), sqrt(-4))
}
Note: The conditional expression do not have to be included in parentheses (...) in contrast to JavaScript and C. After the expression we use braces {...} that are mandatory to create the block of code associated with the decision statement.
The "if" statement has a local scope. That is we can define a local "control variable" to be used inside the if block. That is unusual for a programming language. In the next example variable v is in to local scope of the "if" statement. Variables declared by the statement are only in scope until the end of the "if". If we try using v after the last return statement we will have an error.
Example of local scope variables:
//file if_scope.go
package main
import (
"fmt"
"math"
)
// declare local v using type inference
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
For creation of two blocks of code in decision statement we use the "else" keyword. This is also known as two ways conditional statement. Local variables declared using "if" statement are available in both branches, as expected.
Two ways Decision
//file two_ways.go
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
// Two ways decision with local variable "v"
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// can't use v here, it's gone
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
Go use only one keyword for all iterations: the "for" keyword. This can define a finite or infinite loop.
The basic "for loop" has three components separated by semicolons:
Iteration Diagram
Notes: The "init" statement will often be a short variable declaration, and the variables declared there are visible only in the scope of the for statement. After every iteration, the "post" statement will be executed. The loop will stop iterating once the condition evaluates to false.
Next example will sum all numbers from 0 to 9. The result should be 50.
//file iteration.go
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
Notes:: Unlike other languages Go, or Golang there are no parentheses surrounding the three components of the for statement. However the braces {...} for the block are always required. The "init" and "post" statement are optional.
Go, do not have "while" statement. This may be a surprise, but we can emulate the use-case of "while" by using the "for" statement with conditional but no "init" and no "post" statements.
While Loop
Example of for with no "init: and no "post". It may be curios how the single semicolon is still necessary. So it looks like a conditional between two semicolons. That is what learning Go is all about. Be careful to details, don't let yourself intimidated.
//file while_loop.go
package main
import "fmt"
func main() {
sum := 1
for ;sum < 1000; {
sum += sum
}
fmt.Println(sum)
}
To simulate an infinite iteration we use a for loop with no condition and no control variable. Infinite loops are evil. You must avoid making an infinite loop at all cost. You must use a breack or exit condition, otherwise your stoftwarw will get stuck and never terminate.
Infinite Loop
package main
func main() {
for { }
}
The switch statement is a multi-path conditional selection statement. This allow program to execute on different logical path depending on value of one variable. A switch statement use 2 multiple keywords to create a multi-case construct. The keywords are: {switch, case, default, fallthrough}
Switch Diagram
The switch use a control variable that is local to the case statement. In next example we use "os" variable to analyze the operating system. Switch cases evaluate cases from top to bottom, stopping when a case succeeds.
//file switch_val.go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}
}
Note: When a case control variable has a particular case value switch breaks automatically and no other case is executed except when the case last statement is a fallthrough statement. The last is the "default" case is executed when variable has a different value from any other cases.
Switch without a condition is the same as "switch true". This switch can be used to create a multi-deck conditional construct similar to multiple cascading if statements. This construct can be a clean way to write long if-then-else chains.
//file switch_con.go
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
}
Read next: Functions