Go Tutorial - Section 3

Welcome to the third section of this tutorial. Just like before, I am assuming that you have already completed the previous two sections of the series. If you haven't here are the links:

  1. Section 1 - Deals with setting up your environment, the basic structure of a go program, syntax and data types.

  2. Section 2 - Deals with variables, constants, operators and decision making.

In this section, we will deal with the next set of concepts.

  1. Loops

  2. Control Statements

  3. Switch Case

  4. Functions


Loops


What are Loops?

While writing a solution to a problem, you may face a situation when you want to repeat a specific set of instructions multiple times. This is where loops come into the picture. In general, a loop helps you to repeat the same set of instruction. Imagine solving a problem of printing all natural numbers from 1 to 100. How can you solve this? One way is to write 100 print statements. Is that a good way to write code? What happens when your limit increases to 1000 or say 100000. You cannot write so many print statements. This is where you use a loop.

Though other programming languages support multiple kinds of looping mechanism, to keep things simple, Go uses a single method called the 'for' loop. If you are coming from another language you would know that for is the simplest form of looping available to the coding fraternity. Syntax:

for initialization; condition; post{
       // statements....
}

Here,

  • The initialization statement is optional and executes before for loop starts. The initialization statement is always in a simple statement like variable declarations, increment or assignment statements, or function calls.

  • The condition statement holds a boolean expression, which is evaluated at the starting of each iteration of the loop. If the value of the conditional statement is true, then the loop executes.

  • The post statement is executed after the body of the for-loop. After the post statement, the condition statement evaluates again and if the value of the conditional statement is false, then the loop ends.

Let us go back to the example of printing numbers from 1 to 100. How will you write the code by using a loop?

 package main
 import "fmt"
 
 func main() {
  for i:=1; i<100; i++ {
   fmt.Printf(i)
  }
 }

In the example, I am using a variable 'i' and use a loop to print the value and then increment it. As soon as 100 is printed, the value of 'i' becomes 101 and the condition becomes false resulting in terminating the loop. Infinite Loop

A loop becomes an infinite loop if its condition never becomes false. Since none of the three expressions that form the for loop is required, you can make an endless loop by leaving the conditional expression empty or bypassing true to it.

package main  
import "fmt"    
func main() {   
    for i:=1; ; i++ {    
        fmt.Printf(i)   
     }
 }

When the conditional expression is absent, it is assumed to be true. You may have an initialization and increment expression.


Control Statements


The control statements in the Go language are used to change the execution of the program. When the execution of the given loop left its scope, then the objects that are created within the scope are also demolished. The Go language supports 3 types of loop control statements Break Statement

The break statement is used to terminate the loop or statement in which it presents. After that, the control will pass to the statements that present after the break statement, if available. If the break statement present in the nested loop, then it terminates only those loops which contains break statement. Example:

package main
import "fmt"

func main() {
    for i:=0; i < 100; i++ {
       if i == 5  {
          break
       }
       fmt.Printf(i)
    }
}

Output:

0
1
2
3
4

Continue Statement

This statement is used to skip over the execution part of the loop on a certain condition. After that, it transfers the control to the beginning of the loop. Basically, it skips its following statements and continues with the next iteration of the loop. Example:

package main 
import "fmt"  
func main() {     
    for i:=0; i <= 5; i++ {        
        if i == 4  {           
            continue        
        }        
        fmt.Printf(i)     
    } 
}

Output

0
1
2
3
5

Goto Statement

This statement is used to transfer control to the labelled statement in the program. The label is the valid identifier and placed just before the statement from where the control is transferred. Generally, the goto statement is not used by the programmers because it is difficult to trace the control flow of the program.


Example:

package main 
import "fmt"  
func main() {    
    var i int = 0 
    LabelX: i <= 5 {    
        fmt.Printf(i)    
        if i == 5  {   
            i++        
            goto LabelX        
        }             
     } 
 }

Output

0
1
2
3
4
5

Switch Case


A switch statement is a multiway branch statement. It provides an efficient way to transfer the execution to different parts of a code based on the value(also called case) of the expression. Go language supports two types of switch statements


Expression Switch

Expression switch is similar to switch statement in C, C++, Java language. It provides an easy way to dispatch execution to different parts of code based on the value of the expression.


Syntax

switch optstatement; optexpression{
case expression1: Statement..
case expression2: Statement..
...
default: Statement..
}

Pointers:

  • Both optstatement and optexpression in the expression switch are optional statements.

  • If the switch does not contain any expression, then the compiler assumes that the expression is true.

  • The optional statement, i.e, optstatement contains simple statements like variable declarations, increment or assignment statements, etc.

  • If a variable present in the optional statement, then the scope of the variable is limited to that switch statement.

  • In the switch statement, the case and default statement do not contain any break statement.

  • The default statement is optional in a switch statement.

  • If a case does not contain any expression, then the compiler assumes that the expression is true.

Type Switch

Type switch is used when you want to compare types. In this switch, the case contains the type which is going to compare with the type present in the switch expression.

Syntax

switch optstatement; typeswitchexpression{
case typelist 1: Statement..
case typelist 2: Statement..
...
default: Statement..
}

Pointers:

  • The optional statement, i.e., optstatement is similar as in the switch expression.

  • The default statement is optional in type switch statement.

  • The typeswitchexpression is an expression whose result is a type.

  • If an expression is assigned in typeswitchexpression using := operator, then the type of that variable depends upon the type present in case clause. If the case clause contains two or more types, then the type of the variable is the type in which it is created in typeswitchexpression.

Example

package main 
  
import "fmt"
  
func main() { 

// Example of expression switch
    var value string = "five"
    switch value { 
      case "one": 
        fmt.Println("C#") 
      case "two", "three": 
        fmt.Println("Go") 
      case "four", "five", "six": 
        fmt.Println("Java") 
    }
 
  // Example of type switch   
    var value interface{}
    switch q:= value.(type) { 
       case bool: 
         fmt.Println("value is of boolean type") 
       case float64: 
         fmt.Println("value is of float64 type") 
       case int: 
         fmt.Println("value is of int type") 
       default: 
         fmt.Printf("value is of type: %T", q) 
         
   } 
}

Functions


A function is a group of statements that together perform a task. Every Go program has at least one function, which is main(). You can divide your code into separate functions.


Functions are generally the block of codes or statements in a program that gives the user the ability to reuse the same code which ultimately saves the excessive use of memory, acts as a time saver and more importantly, provides better readability of the code. So basically, a function is a collection of statements that perform some specific task and return the result to the caller. A function can also perform some specific task without returning anything.


A function declaration tells the compiler about a function name, return type, and parameters. A function definition provides the actual body of the function.


The Go standard library provides numerous built-in functions that your program can call. For example, the function len() takes arguments of various types and returns the length of the type. If a string is passed to it, the function returns the length of the string in bytes. If an array is passed to it, the function returns the length of the array.

Functions are also known as a method, subroutine, or procedure.

Syntax for function declaration

func function_name(Parameter-list)(Return_type){
    // function body.....
}

A function definition in the Go programming language consists of a function header and a function body. Here are all the parts of a function −

  • func − It starts the declaration of a function.

  • function_name − It is the actual name of the function. The function name and the parameter list together constitute the function signature.

  • Parameter-list − A parameter is like a placeholder. When a function is invoked, you pass a value to the parameter. This value is referred to as an actual parameter or argument. The parameter list refers to the type, order, and the number of the parameters of a function. Parameters are optional; that is, a function may contain no parameters.

  • Return_type − A function may return a list of values. The return_types is the list of data types of the values the function returns. Some functions perform the desired operations without returning a value. In this case, the return_type is not required.

  • Function Body − It contains a collection of statements that define what the function does.

Example

/* function returning the max between two numbers */
func max(num1, num2 int) int {
   /* local variable declaration */
   result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

While creating a Go function, you give a definition of what the function has to do. To use a function, you will have to call that function to perform the defined task.

When a program calls a function, the program control is transferred to the called function. A called function performs a defined task and when its return statement is executed or when its function-ending closing brace is reached, it returns the program control back to the main program.

To call a function, you simply need to pass the required parameters along with its function name. If the function returns a value, then you can store the returned value. Let's take the above example and convert it into a working program.

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 100
   var b int = 200
   var ret int

   /* calling a function to get max value */
   ret = max(a, b)

   fmt.Printf( "Max value is : %d\n", ret )
}

/* function returning the max between two numbers */
func max(num1, num2 int) int {
   /* local variable declaration */
   var result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

Function Arguments

Go language supports two ways to pass arguments to your function


Call By Value

This method copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument. Example

package main 
   
import "fmt"
   
// function which swap values 
func swap(a, b int)int{ 
  
    var o int
    o= a 
    a=b 
    b=o 
     
   return o  
} 
   
// Main function 
func main() { 
 var p int = 10 
 var q int = 20 
  fmt.Printf("p = %d and q = %d", p, q) 
   
 // call by values 
 swap(p, q) 
   fmt.Printf("\np = %d and q = %d",p, q) 
} 

Output:

p = 10 and q = 20
p = 10 and q = 20

Call by Reference

This method copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. This means that changes made to the parameter affect the argument. Example

package main 

import "fmt"

// function which swap values 
func swap(a, b *int)int{ 
   var o int
   o = *a 
   *a = *b 
   *b = o 
   
return o 
} 

// Main function 
func main() { 

var p int = 10 
var q int = 20 
fmt.Printf("p = %d and q = %d", p, q) 

// call by reference 
swap(&p, &q) 
   fmt.Printf("\np = %d and q = %d",p, q) 
} 

Output

p = 10 and q = 20
p = 20 and q = 10

Ways to use a function Go provides us with three ways to use a function.


Function as value

Go programming language provides the flexibility to create functions on the fly and use them as values. Example

package main

import ("fmt" "math")

func main(){
   /* declare a function variable */
   getSquareRoot := func(x float64) float64 {
      return math.Sqrt(x)
   }

   /* use the function */
   fmt.Println(getSquareRoot(9))
}

Function Closures

Go programming language supports anonymous functions which can acts as function closures. Anonymous functions are used when we want to define a function inline without passing any name to it. Example

package main

import "fmt"

func getSequence() func() int {
   i:=0
   return func() int {
      i+=1
      return i  
   }
}

func main(){
   /* nextNumber is now a function with i as 0 */
   nextNumber := getSequence()  

   /* invoke nextNumber to increase i by 1 and return the same */
   fmt.Println(nextNumber())
   fmt.Println(nextNumber())
   fmt.Println(nextNumber())
   
   /* create a new sequence and see the result, i is 0 again*/
   nextNumber1 := getSequence()  
   fmt.Println(nextNumber1())
   fmt.Println(nextNumber1())
}

Output

1
2
3
1
2

Method

Go programming language supports special types of functions called methods. In method declaration syntax, a "receiver" is present to represent the container of the function. This receiver can be used to call a function using "." operator.

Please note: Do not worry if you don't understand the example right now. We will go into details in later sections.


Example

package main

import (
   "fmt" 
   "math" 
)

/* define a circle */
type Circle struct {
   x,y,radius float64
}

/* define a method for circle */
func(circle Circle) area() float64 {
   return math.Pi * circle.radius * circle.radius
}

func main(){
   circle := Circle{x:0, y:0, radius:5}
   fmt.Printf("Circle area: %f", circle.area())
}


Output

Circle area: 78.539816

This brings us to the end of the third section of this tutorial. Next up will an assignment covering the concepts we have learned till now. Make sure to complete the assignment genuinely. Doing so will help you understand the concepts clearly.

 

+919853340643

©2020 by Aman Sinha.