If
In programming often we have to have conditional execution of certain statements. In most programming languages we have the idea of if
.
var x = 10
if x > 5 {
fmt.Println("x is greater than 5")
}
In this example we have a variable x
which has value of 10. Then we check whether or not x
is greater than 5. If it is, we print something. Otherwise we do nothing.
if - else if - else
Often we are checking for more than one related thing. Lets take the example of FizzBuzz
problem. For any number n, we want to print Fizz
if n is divisible by 3, Buzz
if n is divisible by 5, FizzBuzz
if n is divisible by both 3 and 5 and n if its not divisible by either 3 or 5.
if n%15 == 0 {
fmt.Println("FizzBuzz")
} else if (n % 5) == 0 {
fmt.Println("Buzz")
} else if (n % 3) == 0 {
fmt.Println("Fizz")
} else {
fmt.Println(n)
}
We can chain as many if-else if as we want. else is a special case where we do not have to have a conditional operator. It matches the case that no if - else if conditions match.
It is almost always possible to skip the else branch in functions. For example
func isEven(n int) bool {
if n%2 == 1 {
return false
}
return true
}
Instead of having a else block we can just return the default case.
If with statement
Sometimes we want to check some condition of variable we just created and we only need the variable for the condition. An example might help clear this up a bit more.
func minRand(min int) int {
rand.Seed(time.Now().UnixNano())
if v := rand.Int(); v > min {
return v
}
return min
}
We have a random number v
and if v is greater than min
we return v
if not we would just return min
. We do not need access to v
outside the if condition. This helps us with readability as well as variable naming. In go we are not allowed to redefine a variable with a different type. In a large function having every variable in the same scope might cause trouble.
For
In programming we sometimes need to do something multiple times. We achieve this using loops. Go has only one construct for looping. It is the for
keyword. But for
is pretty versatile in go where we do not need anything else like do-while
, while
like in some other language.
Anatomy of for
Generally a for
loop has this structure
for i := 0; i < 100; i++ {
}
We have a init that initializes our loop invariant. Then we have a condition that is used to terminate the loop and we have a change that is run after each loop iteration.
All three of these are optional and can be used or omitted as we need.
for i := 0; i < 5; i++ {
fmt.Println(i)
}
for i := 0; ; {
if i >= 5 {
break
}
fmt.Println(i)
i++
}
i := 0
for i < 5 {
fmt.Println(i)
i++
}
i = 0
for ; ; i++ {
if i >= 5 {
break
}
fmt.Println(i)
}
for i := 0; i < 5; {
fmt.Println(i)
i++
}
i = 0
for ; i < 5; i++ {
fmt.Println(i)
}
for i := 0; ; i++ {
if i >= 5 {
break
}
fmt.Println(i)
}
i = 0
for {
if i >= 5 {
break
}
fmt.Println(i)
i++
}
These are all possible combination of a for loop with a single invariant. All of these for loop do the exact same thing.
Break
At any point in the for
execution we can use the break
statement to break out of the closest for
loop.
Mutli invariant for loop
We can also have for loops where we have two variables.
for i, j := 0, 10; i != j; i, j = i+1, j-1 {
fmt.Println(i, j)
}
The basic structure is the same. We have a init where we initialize i
and j
. Condition to chech i != j
and then we increase i
and decrease j
.
Forever
If we run a for loop with no exit condition we runt he for loop forever. There are times we want to run a process indefinitely.
for{
// do work indefinitely
}
For example if we look at the source code for net/http we can see an example of indefinite for loop that waits for new connection to server.
Next Steps
This is Part 8 of this Go crash course series.