Using conditionals
Go supports two types of conditionals, as follows:
if
/else
blocksswitch
blocks
The standard if
statement is similar to other languages with the addition of an optional init
statement borrowed from the standard C-style for
loop syntax.
switch
statements provide a sometimes-cleaner alternative to if
. So, let's jump into the if
conditional.
if statements
if
statements start with a familiar format that is recognizable in most languages:
if [expression that evaluates to boolean] { ... }
Here's a simple example:
if x > 2 { fmt.Println("x is greater than 2") }
The statements within {}
in if
will execute if x
has a value greater than 2
.
Unlike most languages, Go has the ability to execute a statement within the if
scope before the evaluation is made:
if [init statement];[statement that evaluates to boolean] { ... }
Here is a simple example that is similar to the init statement in a for
loop:
if err := someFunction(); err != nil { fmt.Println(err) }
Here, we initialize a variable called err
. It has a scope of the if
block. If the err
variable does not equal the nil
value (a special value that indicates certain types are not set – more on this later), it will print the error.
else
If you need to execute something when the condition of an if
statement is not met, you can use the else
keyword:
if condition { function1() }else { function2() }
In this example, if the if
condition is true, function1
will be executed. Otherwise, function2
occurs.
It should be noted that most uses of else
can generally be eliminated for cleaner code. If your if
condition results in returning from a function using the return
keyword, you can eliminate else
.
An example is as follows:
if v, err := someFunc(); err != nil { return err }else{ fmt.Println(v) return nil }
This can be simplified to the following:
v, err := someFunc() if err != nil { return err } fmt.Println(v) return nil
Sometimes, you want to only execute code if the if
condition is not met and another condition is. Let's look at that next.
else if
An if
block can also contain else if
, providing multiple levels of execution. The first if
or else if
that is matched in order is executed.
Note that often Go developers choose the switch
statement as a cleaner version of this type of conditional.
An example is as follows:
if x > 0 { fmt.Println("x is greater than 0") } else if x < 0 { fmt.Println("x is less than 0") } else{ fmt.Println("x is equal to 0") }
Now that we have seen the basics of this conditional, we need to talk about brace style.
if/else braces
It's time to introduce this rule: Opening braces for if
/else
must be on the line with the associated keyword. If there is another statement in the chain, it must start on the same line as the previous close brace.
With many languages, there are arguments about where to put the braces for loops/conditionals.
With Go, the authors decided to pre-empt those arguments with compiler checks. In Go, you can't do the following:
if x > 0 { // This must go up on the previous line fmt.Println("hello") } else { // This line must start on the previous line fmt.Println("world") }
So, with the arguments on bracing style in Go settled, let's look at an alternative to if
/else
, the switch
statement.
The switch statement
switch
statements are more elegant if
/else
blocks that are very flexible in their use. They can be used for doing exact matching and multiple true/false evaluations.
Exact match switch
The following is an exact match switch
:
switch [value] { case [match]: [statement] case [match], [match]: [statement] default: [statement] }
[value]
is matched against each case
statement. If it matches, the case
statement executes. Unlike some languages, once a match occurs, no other case is considered. If no match occurs, the default
statement executes. The default
statement is optional.
This has a nicer syntax than if
/else
for handling cases where your value can be several values:
switch x { case 3: fmt.Println("x is 3") case 4, 5: // executes if x is 4 or 5 fmt.Println("x is 4 or 5") default: fmt.Println("x is unknown") }
switch can also have an init
statement, similar to if
:
switch x := someFunc(); x { case 3: fmt.Println("x is 3") }
True/false evaluation switch
We can also eliminate [match]
so that each case
statement isn't an exact match, but a true/false evaluation (as with if
statements):
switch { case x > 0: fmt.Println("x is greater than 0") case x < 0: fmt.Println("x is less than 0") default: fmt.Println("x must be 0") }
At the end of this section, you should be able to use Go's conditional statements to branch code execution in your program based on some criteria and handle cases where no statement was matched. As conditionals are one of the standard building blocks of software, we will use these in many of the remaining sections.