Golang Control Flow

As we have covered Golang ‘language fundamentals’ in our Third Chapter, let’s explore ‘Control Flow’ and ‘Functions’ in this chapter.

The golang control flow statements are used to break the flow of execution by branching, looping, decision making statements by enabling the program to execute code based on the conditions. All programmers must know the control flows like if-else, switch case, for loop, break, continue, return.

  • if/else
  • if/else if/else
  • if/else if/else if/…../else

The if statement is similar to other programming languages. If statement is expecting some condition and based on the condition it will execute the code.

if condition { 
//Executable code
}
if condition {
//Executable code
}else 
{
//Executable code
}
if condition
//Executable code
}else if condition{ 
//Executable code
} else{
//Executable code 
}

Note: use else/else if just after closing of if statement’s closing bracket “}“ otherwise you will get compile time error.

main.go
package main
import (
 "fmt"
)
func main() {
 no := 56
 if true {
 fmt.Println("This will work")
 }
 if false {
 fmt.Println("This will not work")
 }
 if !true {
 fmt.Println("This will not work")
 }
 if !false {
 fmt.Println("This will work")
 }
 n := 45
 if n%2 == 0 {
 fmt.Println("even")
 } else { //use else just after “}” end of if
 fmt.Println("odd")
 }
 //If with short statement
 if computer := "Dell"; no > 50 {
 fmt.Println(computer)
 }
}

Demo Screenshot –

For Loop

Golang has only one loop which for a loop. Like other programming languages, it doesn’t have while and do while loop. But we can use for loop as while loop.

for initialization;condition;increment/decrement{
 //Executable code
 }
package main

import (
 "fmt"
)
func main() {
 //Nested for loop
 for i := 1; i <= 5; i++ {
 for j := 1; j <= 10; j++ {
 fmt.Print("\t")
 fmt.Println(j * i)
 }
 }
 //for as a while loop
 k := 0
 for k < 10 {
 fmt.Println(k)
 if k >= 10 {
 break //break statement is used to break the control if cond occurs
 }
 k++
 }
 //for with no condition
 m := 0
 for {
 fmt.Println(m)
 if m >= 10 {
 break
 }
 m++
 }
 for i := 65; i <= 122; i++ {
 fmt.Printf("%v - %v - %v \n", i, string(i), []byte(string(i)))
 //converted int type to string and []byte
 }
}

Switch Case

Most programming languages have switch case to avoid complex if-else if statements.

  • we can compare only values of the same types
  • we can set optional default statement if the condition fails
  • we can use expression if need to compare condition based on value to use
switch value/cond {
 case ‘value/cond’: executable code
 case ‘value/cond’: executable code
 …..
 default : default statements if all above fails.
 }

“fallthrough” is optional in switch case. This keyword is used in case statement and when it is encountered, it will go to next case even if next case is failing condition. So it is optional in this switch case.

We can specify multiple values in the case statement. Also, we can return a value based on switch cases.

main.go
package main
import (
 "fmt"
)
func main() {
 test("one")
}
func test(str string) {
 val := str
 switch val {
 case "zero",”Zero”:
 fmt.Println("Zero:", val)
 fallthrough /*even if next condition fails
 it will enter into next case */
 case "one",”One”:
 fmt.Println("One:", val)
 break
 default:
 fmt.Println("Wrong one !!")
 }
}

Normally we switch on the value of a variable but Golang allows you to switch on type also.

main.go
package main
import (
 "fmt"
)
type wish struct {
 message string
 name string
}
func Type(x interface{}) {
 switch x.(type) { //this one is assert
 case int:
 fmt.Println("int")
 case string:
 fmt.Println("string")
 case wish:
 fmt.Println("wish")
 default:
 fmt.Println("Unknown Type")
 }
}
func main() {
 Type(7)
 Type(wish{"Good Morning", "User"})
}

Functions

Functions are no. of statement that together performs a task and makes execution flow more reliable so that we can reuse the code whenever needed.

The execution of the Go program starts from the main function itself func main(){ }. A function takes one or more parameters and returns one or more outputs. Like other programming languages, go explicitly needs to return values.

Are You Looking For Golang Development Services?

The Syntax is

func <function name>(parameters)(return types){
 …………….//Executable code
 return <value> //If function is returning
}

The function starts with keyword func and its name. The parameters need to define like var_name var_type. After this, we need to write a return type if a function is going to return. Writing of function can be difficult so a better idea is to break into manageable code, rather than going for full implementation.

func square(n int)(int){
 return n*n
 }

The return statement is used to immediately stop and return value to its caller. Go has the capability to return multiple values.

x,y:=func(5)
 func(n int)(int,int)
 {
a:=8
return a,n
}

Mostly we are returning result along with error like x,err =func(). Avoid using nameless return.

Variadic Function

This one is a special form of function which can take any arguments. It is like varargs in Java. We can pass any number of parameters to the variadic function of the same type. To make function variadic you just need to put three dots … before the arguments type. It will allow you to pass any number of arguments to the function.

func sum(args ..int)int{ //Variadic function
 total:=0
 for value:=range args{
 total+=value
 }
 return sum
 }
 func main(){
 fmt.Println(sum(54,76,43,23,78)) //Passing multiple values
 data:=[]int{33,87,43,21} //Passing Slice of ints
 fmt.Println(sum(data...))

Here, you can see how the fmt.Println() is implemented in “fmt” package. func Println(a …interface{})(n int,err error)

So the Println function can take any number of arguments of any type. We can also pass a slice of ints for the variadic function.

func main(){
xs:=[]int{43,67,43,21}
fmt.Println(sum(xs…))
}

Function as expression

We can pass a function to expression and call that function by using expression/variable name. This is the only way to have one function inside another.

If you see the type of expression then it will be a func()

func main(){
message:=func(){
fmt.Println(“Good Morning User”)
}
message() //calling function by expression name/var name as anonymous fun
fmt.Printf(“%T”,message) //Its type will be a func()

No identifier is there and function is anonymous(nameless)

Closure

We can create a function inside functions i.e. nesting of functions.

For this purpose, Go supports anonymous function i.e. function without a name which will become local to the function.

func main(){
 sum:=func (x,y int)(int){
 return x+y
 }
 fmt.Println(“Sum is”,sum())
}

Closure helps us limit the scope of variables used by multiple functions. Without closure, for two or more funcs to have access to same variable, that variable would need to be in package scope.

Callbacks

Passing a function as an argument is called callback in golang. Here, we can pass a function as an argument.

func main(){
 show([ ]int{43, 76, 34}, func(n int) {
 fmt.Println(n)
 })
}

 func show(numbers [ ]int, call func(int)) {
 for _, n := range numbers {
 call(n)
 }
}

Here we are passing func call( ) as an argument to the func show( )

Recursion

Recursion is a function which calls itself. It is like two mirrors facing to each other.

func factorial(n int) int {
 if n==1{
 fmt.Println(n)
 }
 return n*factorial(n-1) //factorial() will call itself till it reaches to 0
  • Recursion will create a stack of function calls every time.
  • Sometimes recursion is the best solution.
  • Closure and Recursion are the powerful technique of programming which forms functional programming and most of the people find recursion difficult to understand than the control flow statements.

Defer

Go has a special statement defer which schedules a function call to execute before function completes.

Defer is used when resources need to be freed away i.e. same like finally block in java which is used to put the resource releasing logic.

For ex. Whenever we open a file we need to make sure to close it or while connecting to the database after completion of the task we need to close the connection.

f,_:=os.Open(“filename.txt”)
defer f.Close()

Advantages→

  • It keeps our Close() near to the Open() and it’s easy to understand
  • deferred func will always run even if runtime panic err occurs

Pass By value

Strictly speaking, there is only one way to pass parameters in Go is Pass By Value. Whenever a variable is passed as a parameter, a copy of that variable is created and passed to the function and this copy will be at a different memory location.

In case, a variable is passed as a pointer argument then again a new copy of the parameter is created and that will point to the same address.

main.go
 package main
import (
 "fmt"
)
type person struct {
 name string
 age int
}
//Pass by value 
func changeIt(ch person) {
 ch.name = "Rafel"
}
//Pass by value using pointer
func change(ch *person) {
 ch.name = "Rafel"
}
func main() {
 per := person{"Roger", 64}
 changeIt(per)
 fmt.Println(per) //]Here still we are getting old values
 change(&per)
 fmt.Println(per) //Here value is changing
}
Note that even though func changeIt() changes the name to ‘Rafel’, it does not affect the variable name in the main function. This happens because function modifies a copy of the variable, not the original one.

But the func change() is modifying the value because &per and per are two different pointers pointing to the same struct which is stored at the same memory address.

Anonymous Function

Anonymous functions are the self-executing functions which are nameless i.e.they do not have a name. Only through anonymous function, we can do nesting of functions i.e. one function inside another.

func main(){
 func( ){
 fmt.Println(“Hello World...I am Anonymous Function”)
 } ( )
Well, we are now all set with major control flows and functions for Golang. In our next chapter, we will explore Golang Data Structures. Make sure you check it out!

Content Team

This blog is from Mindbowser‘s content team – a group of individuals coming together to create pieces that you may like. If you have feedback, please drop us a message on contact@mindbowser.com

Keep Reading

  • Service
  • Career
  • Let's create something together!

  • We’re looking for the best. Are you in?