Branching
Switch Statements
A simple switch
statement:
switch a + b {
case c:
// do something
case d:
// do something else
default:
// do something entirely different
}
The above example is equivalent to:
if a + b == c {
// do something
} else if a + b == d {
// do something else
} else {
// do something entirely different
}
The default
clause is optional and will be executed if and only if none of the cases compare true, even if it does not appear last, which is acceptable. The following is semantically the same as the first example:
switch a + b {
default:
// do something entirely different
case c:
// do something
case d:
// do something else
}
This could be useful if you intend to use the fallthrough
statement in the default
clause, which must be the last statement in a case and causes program execution to proceed to the next case:
switch a + b {
default:
// do something entirely different, but then also do something
fallthrough
case c:
// do something
case d:
// do something else
}
An empty switch expression is implicitly true
:
switch {
case a + b == c:
// do something
case a + b == d:
// do something else
}
Switch statements support a simple statement similar to if
statements:
switch n := getNumber(); n {
case 1:
// do something
case 2:
// do something else
}
Cases can be combined in a comma-separated list if they share the same logic:
switch a + b {
case c, d:
// do something
default:
// do something entirely different
}
If Statements
A simple if
statement:
if a == b {
// do something
}
Note that there are no parentheses surrounding the condition and that the opening curly brace {
must be on the same line. The following will not compile:
if a == b
{
// do something
}
An if
statement making use of else
:
if a == b {
// do something
} else if a == c {
// do something else
} else {
// do something entirely different
}
Per golang.org’s documentation, “The expression may be preceded by a simple statement, which executes before the expression is evaluated.” Variables declared in this simple statement are scoped to the if
statement and cannot be accessed outside it:
if err := attemptSomething(); err != nil {
// attemptSomething() was successful!
} else {
// attemptSomething() returned an error; handle it
}
fmt.Println(err) // compiler error, 'undefined: err'
Type Switch Statements
A simple type switch:
// assuming x is an expression of type interface{}
switch t := x.(type) {
case nil:
// x is nil
// t will be type interface{}
case int:
// underlying type of x is int
// t will be int in this case as well
case string:
// underlying type of x is string
// t will be string in this case as well
case float, bool:
// underlying type of x is either float or bool
// since we don't know which, t is of type interface{} in this case
default:
// underlying type of x was not any of the types tested for
// t is interface{} in this type
}
You can test for any type, including error
, user-defined types, interface types, and function types:
switch t := x.(type) {
case error:
log.Fatal(t)
case myType:
fmt.Println(myType.message)
case myInterface:
t.MyInterfaceMethod()
case func(string) bool:
if t("Hello world?") {
fmt.Println("Hello world!")
}
}
Goto statements
A goto
statement transfers control to the statement with the corresponding label within the same function.
Executing the goto
statement must not cause any variables to come into scope that were not already in scope at the point of the goto
.
for example see the standard library source code: https://golang.org/src/math/gamma.go :
for x < 0 {
if x > -1e-09 {
goto small
}
z = z / x
x = x + 1
}
for x < 2 {
if x < 1e-09 {
goto small
}
z = z / x
x = x + 1
}
if x == 2 {
return z
}
x = x - 2
p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6]
q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7]
return z * p / q
small:
if x == 0 {
return Inf(1)
}
return z / ((1 + Euler*x) * x)
Break-continue statements
The break statement, on execution makes the current loop to force exit
package main
import "fmt"
func main() {
i:=0
for true {
if i>2 {
break
}
fmt.Println("Iteration : ",i)
i++
}
}
The continue statement, on execution moves the control to the start of the loop
import "fmt"
func main() {
j:=100
for j<110 {
j++
if j%2==0 {
continue
}
fmt.Println("Var : ",j)
}
}
Break/continue loop inside switch
import "fmt"
func main() {
j := 100
loop:
for j < 110 {
j++
switch j % 3 {
case 0:
continue loop
case 1:
break loop
}
fmt.Println("Var : ", j)
}
}