Friday 1 May 2020

GO language Basics

This article covers the basics of GO language.
Go language is popular today due to simple to use, high performance because of its concurrency feature compared to other language like python. Go has garbage collector .

#1  Basic Program

// The program header should contain -> package main
// Also there will be import packages like in python.
// Every function or routine starts with "func" with open braces and closing braces
// fmt.Println -> is used to print the statements.

package main
import  "fmt"

func main(){
   fmt.Println("Hello World")
}

#2 How to define functions 

Tip:  use "func" keyword.
Function can return multiple values with named and unnamed

#prog:2

package main
import  "fmt"

//Declare function with zero or multiple arguments
func  display(){
        fmt.Println("I am in in Display function")
}
func recv(x int, y int){
        fmt.Println("The values of X and Y", x,y)
}

func recv(x int, y int){
        fmt.Println("The values of X and Y", x,y)
}
// Un named return function 
func return_multiple(x int, y int)(int, int){
        return x,y
}
func named_return(b,t string)(z,y string){
   z=b
   t=y
   return
}
func main(){
   fmt.Println("Hello World")
   // Call display function
   display()
   //recv function
   recv(2,3)
   // Function return value
   y:= add(2,4)
   fmt.Println("The Result of addition is", y)

   // Multiple values return by function by unamed
   a,b:= return_multiple(10,11)
   fmt.Println("The values are", a,b)
   
   fmt.println(named_return("mu","sekhar"))

}

O/p:
Hello World
I am in in Display function
The values of X and Y 2 3
The Result of addition is 6
The values are 10 11
mu sekhar

Tip :Short Hand Declaration : a int b int -> a,b int

#3 What are datatypes present in GO?

Boolean types : Consists of the two predefined constants: (a) true (b) false
Numeric types : a) integer types or b) floating point values throughout the program.
String types  : A string type represents the set of string values. 
             
Derived types:
   - Pointer types,   - Array types,     - Structure types,     - Union types 
   - Function types     - Slice types     - Interface types     - Map types     - Channel Types

Basic data Types
bool, string
int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // alias for uint8
rune // alias for int32
     // represents a Unicode code point
float32 float64
complex64 complex128

#4 How to declare or define the variables in GO?

Syntax:   var < variable name> <data type>   e.g: var a int
            short hand --->   variable:= <value>  i:=2

Tip: By Default the variables are assigned to 0 for int, empty (" ") for strings and false for boolean

package main
import "fmt"

func main(){
  //Declaration 1
  var i int
  i=20
  fmt.Println(" The value of i", i)

  // Declaration 2 Short hand
  r:="muni"
  fmt.Println(" The value of r", r)

  var x  int
  var y, f bool
  fmt.Println(x, y,f)

  //intialise the variables
  var x1,y1,z string = "mu", "sekhar", "reddy"
  fmt.Println(x1,y1,z)

  // short Hand initialization
  i,j,k:=1,2,3
  var h,b,n int=10,11,13
  fmt.Println(i,j,k, h,b,n)

  // By Default the values of uninitialized to Zero values
  // f is 0 g false t ="" empty string
  var  m int
  var  g bool
  var  t string

  fmt.Println(m,g,t)

}
Output:
 The value of i 20
 The value of r muni
0 false false
mu sekhar reddy
1 2 3 10 11 13
0 false

#5 How to do Type conversions in GO?

Data-Type<Variable>   for e.g: i:=3   k=float64(i)  z=uint32(i)

Tip: var i int =10  j:=i  - > there is no need explicity mention the type for J.. It variable's type is determined from the value on the right hand side)

#6  How to define Const variables in GO?

Constant variables are declared using keyword "const". const <variable-name>= <value>
package main
import "fmt"

func main(){
   const i=2
   const k="muni"
   const j=8.7
   fmt.Println(i,k,j)
   i=9  // Cannot change constant value
}

Tip: Cons i:=2 // This way of constant cannot be declared. Not allowed

#7  LOOPS in GO

Note: There is no while Loop in Go. The for loop itself act like a while Loop.
Syntax:      for i:=0; i<num; i++ { .. }   
            ->   for { }  -> infinite loop
            ->   i:=0 for i<5; i++ { .... }


package main

import "fmt"



func main(){

  //Basic For Loop

  for i:=0; i<2; i++ {

          fmt.Println(i)

  }

  //initialization and  post increments are optional

  j:=0
  for ; j<2;  j++ {
     fmt.Println("Sekhar")
  }
  // There is no While Loop in GO language
  //While loop
  k:=0
  for k<2 {
     fmt.Println("I am Linux")
     k++
  }
}
Output:
0
1
Sekhar
Sekhar
I am Linux
I am Linux

#8  if-else statement in GO

Syntax:      if  <condition> { 

                   }

                  if  <condition> {

                 } else {

                       .....

                 }   

            
package main
import "fmt"

func main(){
   x:=7
   // x<8 we can have without braces as well.
   if (x<8) {
       fmt.Println(" I am in IF statement")
   } else {
       fmt.Println(" I am in Else Statement")
   }
   // Short Hand initialization
   if k:=99; (k<89) {
       fmt.Println(" K is True ")
   }else {
       fmt.Println(" K is False ")
   }
}

Output:
I am in IF statement

K is False

#9  Switch Statement in GO

There is no switch statement in python. But Go has switch feature.

package main
import "fmt"

func main(){
  ch:="test"
  switch ch {
      case "test":
         fmt.Println(" I am in test Function")
      case "not":
         fmt.Println("I am not case")
      default:
         fmt.Println("I am in default case")
  }
  // Mimic the if-else case
  i:=2
  switch{
     case i<3:
         fmt.Println(" I value is less than 3")
     case  i>3:
         fmt.Println(" I value is greater than 3")
    default:
         fmt.Println("Default Value")
  }
}

Output
------
I am in test Function
I value is less than 3


#9  DEFER Statement in GO

Defer statement -> It  will defer the execution of the statement until the function return.
Program 1 #
---------------
package main
import "fmt"

func main(){
    defer fmt.Println("I am First Function")
    fmt.Println(" I am after Defer Function")

}
Output:
I am after Defer Function
I am First Function

Program 2 #
--------------
package main
import "fmt"

func main(){
    for i:=0; i<2; i++ {
        defer fmt.Println(" The output is :", i)
    }
    fmt.Println(" I am after Defer Function")
}
Output:
I am after Defer Function
The output is : 1
The output is : 0


#10  Pointer in  GO

Pointer is variable which holds the memory address of another variable as in C.  This is used to change the value of variable with the pointer de-referencing operator *

Syntax:  var p *int
               var i int=4    p=&i -> Holds the address of the integer variable i

package main
import "fmt"

func main(){
        var p *int
        var i int
        i=400
        p=&i
        fmt.Println("The value of p and *p", p, *p)
        // Change the value of "i" as below
        *p=300
        fmt.Println("The value of i", i)
}

Output:
The value of p and *p 0xc0000a4010 400
The value of i 300

#11  Struct in  GO

Syntax:   type <struct-name> struct {
                      <variable-name> data-type
                      ......
               }
Defining values of the struct variable as  :  < variable> := <struct-name>
e.g:
type emp struct{
        emp_age  int
        emp_name string
        emp_sal  float64
   }
   x:= emp{1, "sekhar", 2.33}

The value of struct values shall be accessed using  dot(.) operator. (x.emp_age, x.emp_name, x.emp_sal)

Struct Pointer;
p := &x
p.emp_age = 2222  // It can be modified like this.

package main
import "fmt"

func main(){
   type emp struct{
        emp_age  int
        emp_name string
        emp_sal  float64
   }
   x:= emp{1, "sekhar", 2.33}
   fmt.Println(x)
   // Struct Fields can be accessed using '.'(dot)
   fmt.Println(x.emp_age, x.emp_name, x.emp_sal)

   // Struct Pointer
   // It inference the pointer as struct pointer
   p:= &x
   p.emp_age = 111
   fmt.Println(x.emp_age, x.emp_name, x.emp_sal)


   type dummy struct{
           xq ,yq string
   }
   // Various way of initialization values of struct
   d1 :=dummy{"muni","sekhar"}
   d2 :=dummy{xq: "muni"}
   d4 := dummy{}

   fmt.Println(d1)
   fmt.Println(d2)
   fmt.Println(d4)
}

output:
{1 sekhar 2.33}
1 sekhar 2.33
111 sekhar 2.33
{muni sekhar}
{muni }
{ }

#12  Arrays in  GO

Array stores elements of same data type.
Syntax:  [n] data-type  -> It stores the 'n' elements of data-type of T.
              e.g:   var a [7] int
                      Short Hand -> a := [7]{1,2,3,4,5,6,7}
package main
import "fmt"

func main(){
     var X[2] int
     X[0]=1
     X[1]=2
     fmt.Println(X[0], X[1])

     var Z= [3]int{1,2,3}
     fmt.Println(Z)

     Y:= [2] float64{2.00, 3.00}
     fmt.Println(Y)

     str:=[2] string {"muni","sekhar"}
     fmt.Println(str[0], str[1])
}
Output:
1 2
[1 2 3]
[2 3]
muni sekhar

#13  Slices in  GO

Array are fixed size, whereas slices can be dynamically sized, which generally stores the part of elements of the array.
Syntax:  [ ] data-type    -> It contains the elements of corresponding data -type

Slices doesn't store data, it contains the elements of underlying array. Modifying the slice data shall modify the elements of underlying array. i.e.Slices have reference  to array.

package main
import "fmt"

func main(){
   var arr1= [4]int{1,2,3,4}

   arr2 := [5]string{"mu","sek","red","tt","yy"}

   // A slice is formed by specifying two indices,
   // a low and high bound, separated by a colon:
   // a[low : high]

   s := arr2[1:4]
   var t1 []int= arr1[1:4]
   fmt.Println(s, t1)

   fmt.Println(s[0], s[1], s[2])

   // Modifying slice effect to the array.
   //slices have reference to array
   s[2] = "Modified"
   fmt.Println(arr2)
}

Output:
[sek red tt] [2 3 4]
sek red tt
[mu sek red Modified yy]

#13  Create Slices using "make" built-in function 

Syntax:-->  make ([] T, length, capacity)
                e.g:  v := make([] int, 3, 4) -> It creates slice of three elements with zero value and having capacity of 4.

// Slice can be created using "make" built-in function .
// "make" takes two arguments make( []data-type, length, capacity)
// length is used to index the items in the slice. ->len(v)
// capacity is used pre allocated space in the memory and it is optional. -> cap(v)
// Having capacity gives more performance rather than allocating newly using append operations.
//  v := make([] int, 3)  in this case both length and capacity is same as 3.

COPY in slice:     copy(slice1, slice2)
-------------------
APPEND in slice:    sli=append(sli, 2,3)  -> Append 2 and 3 to the existing slice sli.
--------------------
Length of slice ->    len(sli)    Capacity of slice ->  cap(sli)

package main
import "fmt"

func main(){
    // Slice can be created using "make" built-in function
    // make takes two arguments make( []data-type, length, capacity)
    // length is used to index the items in the slice
    // capacity is used pre allocated space in the memory and it is optional
    // Having capacity gives more performance rather than
    //allocating newly using append operations.

    sli := make([]int, 3,4)
    fmt.Println(sli, len(sli),cap(sli))

    // Append to the existing slice
    sli = append(sli, 10,11,12,13)

    fmt.Println(sli, len(sli),cap(sli))

    sli[0]=200
    sli[1]=300
    fmt.Println(sli, len(sli),cap(sli))

    i:= sli[2:]
    j:= sli[:4]
    fmt.Println(i,j)

    dup_sli := make([]int,  len(sli))
    copy(sli, dup_sli)
    fmt.Println(dup_sli)

    //Two dimensional array or Slice
    twoD := make([][]int, 3)
    for k:=0; k<len(twoD); k++{
         inner:= k+1
         twoD[k] = make([]int, inner)
         for  j:=0; j<inner; j++ {
             twoD[k][j]=k+j
         }
    }
    fmt.Println(twoD)
}
Output:
[0 0 0] 3 4
[0 0 0 10 11 12 13] 7 8
[200 300 0 10 11 12 13] 7 8
[0 10 11 12 13] [200 300 0 10]
[0 0 0 0 0 0 0]
[[0] [1 2] [2 3 4]]


3 comments: