Understanding Interfaces in Go

Follow the latest of Whizdumb’s journey here.

In a world full of Object Oriented Languages, we have all worked with Interfaces, they are simple and elegant.

Go borrows the good things from the world of Object Oriented Programming and interfaces are one of the best things there. Lets see how we work with interfaces in Go,

type NamePrinter interface {
    printName()
}

Here we defined an interface called NamePrinter, they look similar to struct but rather than containing fields, interfaces contain methods, an interface can have more than one method.

In the previous post We had defined a struct Person which had a printName() method as shown

package main

import "fmt"

type Person struct {
  FirstName, MiddleName, LastName string 
}
func (p *Person) printName() {
    fmt.Println("The person name is",p.FirstName,p.MiddleName, p.LastName)
} 
func main() {
	p := Person{FirstName:"dumb", LastName:"whiz"}
	p.printName()
}

Now notice that our Interface NamePrinter also has the printName() method, this means that Person struct “implements” NamePrinter Interface. We do not need to explicitly mention that Person “implements” NamePrinter. How can we be sure that NamePrinter is indeed “implemented”?

Lets look at some code here

package main
import "fmt"

type NamePrinter interface {
     printName()
}

type Person struct {
  FirstName, MiddleName, LastName string 
}
func (p *Person) printName() {
    fmt.Println("The person name is",p.FirstName,p.MiddleName, p.LastName)
} 
func main() {
	p := Person{FirstName:"dumb", LastName:"whiz"}
	p.printName()
	checkInterfaceType(&p)
}

func checkInterfaceType(namePrinter NamePrinter){
   NamePrinter(namePrinter).printName()
   fmt.Println("interface type has been checked")
}

So, you have gone through the code. Go back and give it a look again. Seriously. Lets track our steps again the third time.

In the starting we declared our package and imported the fmt package, then we declared a new interface called NamePrinter.

Next we define a struct called Person with name fields in it. Next we define a method called printName() which has been “binded” to Person struct. Notice that the method name and signature is same as that defined in interface NamePrinter.

We start our main function and create a Person type variable with some initial values. In the next line we invoke the method printName() on a variable of Person type.

Fairly good up to this point.

In the next line we call checkInterfaceType function and pass in the “reference to p” or “address of p” (&p) variable.

In the next line checkInterfaceType() method is defined which accept a parameter of type NamePrinter. So that means the “reference of p” (&p) was of type NamePrinter, though we never really explicitly defined it anywhere. Inside the checkInterfaceType() function, we call printName() method on a variable referenced by NamePrinter.

Here is the output of the above code

The person name is dumb  whiz
The person name is dumb  whiz
interface type has been checked

The person type can implement multiple interfaces this way.

Go back and read this post again! Seriously!

~~ Whizdumb ~~

Advertisements

Introducing Structures and Methods

Follow the latest of Whizdumb’s journey here.

Like in all programming languages, Go also provides a way to create your own data types by combining two or more basic types.

To do that Go provide us with struct keyword. Lets try and create a new type “Person”. All we need to do is

type Person struct {} 

Lets add some fields to person

type Person struct {
  FirstName, MiddleName, LastName string 
}

Now lets create an instance for this Person

var p Person

This creates an instance of Person referred by p and initialises all fields in Person to empty strings. If we try to print values for person p, we will get empty strings. Following code demonstrates that.

package main
import "fmt"
type Person struct {
  FirstName, MiddleName, LastName string 
} 
func main() {
	var p Person
	fmt.Println("The person name is ", p.FirstName, p.MiddleName, p.LastName)
}

This gives output

The person name is    

Here also notice how we accessed the fields of Person using “.” (dot) operator.

We can also use the new function to create variable.

p := new(Person)

Thing to note here is that it will return a pointer to the Person, so p here in essence is pointer to the Person struct. p is of type *Person

Now lets try to create a new variable and set some values for name of the person

 p := Person{FirstName:"dumb", LastName:"whiz"}

If we try to print the names now, we will get the person name. Here is how the program looks like with output

package main

import "fmt"

type Person struct {
  FirstName, MiddleName, LastName string 
} 
func main() {
	p := Person{FirstName:"dumb", LastName:"whiz"}
	fmt.Println("The person name is",p.FirstName,p.MiddleName, p.LastName)
}

output :

The person name is dumb  whiz

We can create a function which accepts person as a parameter and prints the name. But, what if we wanted to invoke a function on Person type, like p.printName() where p is a variable of Person type.

Go provides a way to “bind” functions to a particular type and such functions are knowns as methods. Lets see how we do it

func (p *Person) printName() {
    fmt.Println("The person name is",p.FirstName,p.MiddleName, p.LastName)
} 

In the above code we define a method printName() which accepts no parameter but can be invoked by a variable of type Person.

Here is the complete code sample

package main

import "fmt"

type Person struct {
  FirstName, MiddleName, LastName string 
}
func (p *Person) printName() {
    fmt.Println("The person name is",p.FirstName,p.MiddleName, p.LastName)
} 
func main() {
	p := Person{FirstName:"dumb", LastName:"whiz"}
	p.printName()
}

Neat!

~~ Whizdumb ~~

Can you do that later Please, but don’t forget it, its important

Follow the latest of Whizdumb’s journey here.

We all have been in a situation in real life, where we need to get a thing done, which needs to be done by the end of a day or by the end of some time frame. You can not afford to forget it or delay it any longer. Think going into production on Friday!, you want to done over with it on Friday itself and not take it over to the weekend!

Such situations happen in programming too, where you need to get a thing done, you can delay it to later but it must be done under all circumstances.

Think of closing those open connections to database, which need to be closed even if an exception occurs. You can afford to close them at some later time, but they must be closed.

In java we do that in finally block.

In comes the defer in go-lang. Defer delays the statement to be executed till the end of the function and ensures that the deferred statement is executed.

Lets understand it in Detail

Consider the following code

package main
import "fmt"

func main() {   
    x := 1    
    defer fmt.Println ("The value of x is ", x)
    x = 10
    defer fmt.Println ("The updated value of x is ", x)
}

In this we have deferred both our Print calls. Defer calls act like a stack, so in this case the last deferred call will be executed first and then the first call.

So we will see “The updated value of x is ” before “The value of x is “. Here is the output

The updated value of x is  10
The value of x is  1

Notice that even though the value of x has been updated to 10, the deferred call still takes the value as 1, which would have been the output had the call not been deferred!

But does it ensure that our deferred calls are always executed even if there is an unexpected situation occurring. Lets check it.

package main
import "fmt"
func main() {   
    x := 1    
    fmt.Println("Everything is good")
    defer fmt.Println ("The value of x is ", x)
    x = 10
    fmt.Println("Panic is going to occur now!!")
    panic("Lord Voldemort has returned!!")
    fmt.Println("Panic has occured!")
    defer fmt.Println ("The updated value of x is ", x)
}

In the above code we have a panic statement, there is a defer before the panic and a defer after the panic. Lets look at the output

Everything is good
Panic is going to occur now!!
The value of x is  1
panic: Lord Voldemort has returned!!

goroutine 16 [running]:
runtime.panic(0xfc0c0, 0x1030e0f8)
	/tmp/sandbox/go/src/pkg/runtime/panic.c:279 +0x120
main.main()
	/tmpfs/gosandbox-e65a337d_cc5e9f3f_1ba937ab_6eecf9d9_0feba4c1/prog.go:10 +0x320

goroutine 19 [runnable]:
runfinq()
	/tmp/sandbox/go/src/pkg/runtime/mgc0.c:2606
runtime.goexit()
	/tmp/sandbox/go/src/pkg/runtime/proc.c:1445
 [process exited with non-zero status]

In the output we can see that first defer statement which ideally should have been printed in the last has been printed whereas print statements after the panic have not been printed.
Indeed the last deferred statement has not been printed because the runtime never got there.

We should always write deferred statements which must be executed as early as we possibly can to reduce their chances of not being run like the last deferred statement.

Thing to note is defer is a function level construct. Deferred statements execute as the last statements before the function returns.

Later!

~~ Whizdumb ~~

Continuing with variadic functions in Go

Follow the latest of Whizdumb’s journey here.

Now that we know, about variadic functions Lets explore them a little more.

The most common variadic function we have been using all along is fmt.Println().

We can use that function to print just a String.

package main
import "fmt"

func main() {       
    fmt.Println("Hi this is a sample string")  
}


or we can print a string and a float

package main
import "fmt"

func main() {       
    fmt.Println("Hi this is a sample string", 4.5)  
}

or we can print a string, a float and multiple int values

package main
import "fmt"

func main() {       
    fmt.Println("Hi this is a sample string", 4.5, 4,5,6,67,23)  
}

Notice the different types here along with different number of arguments. How does Println function does that?

From the documentation, the println function looks like

func Println(a ...interface{}) (n int, err error)

So it can accept multiple parameters of type interface{}, we will explore interface{} later, but for now lets take it that it allows Println to account for all basic type

It also has 2 return types one int and one error, Here is how they work

package main
import "fmt"
func main() {
    x,y := fmt.Println("Hello, world")
    fmt.Println(x,y)
}

If all goes well the above code prints

Hello, world
13 

Signifying that 13 bytes were written and no error was encountered.

Lets explore another function, lets try to append value of one slice to another slice. We will use builtin append function. The signature of append function looks like

func append(slice []Type, elems ...Type) []Type

It accepts a slice as a first argument and thereafter variable number of arguments. But how can we use it to append one slice to another. We can explode the second slice to append it behind the first. Here is how to do it

package main
import "fmt"
func main() {
     x := []int{
    48,96,86,68,
    57,82,63,70,
    37,34,83,27,
    19,97, 9,17,
}   

  y := []int{
    48,96,86,68,
    57,82,63,70,
    37,34,83,27,
    19,97, 9,17,
}   

   z:= append(x,y...)
   fmt.Println(z)

}

Notice the line z:= append(x,y…) . The … behind slice y are very important since they tell the compiler to actually explode the slice and pass in each value as a parameter to the function. The output from above code is

[48 96 86 68 57 82 63 70 37 34 83 27 19 97 9 17 48 96 86 68 57 82 63 70 37 34 83 27 19 97 9 17]

Later!

~~ Whizdumb ~~

Passing variable number of arguments in a function

Follow the latest of Whizdumb’s journey here.

Continuing with our learning of functions in go, lets now explore how a function can accept variable number of arguments in a function.

Lets modify calculateMinimumAndMaximum(x []int) (int,int) from previous post to accept a variable number of arguments rather than an array or slice.

Lets update the function signature and definition first.

func calculateMinimumAndMaximum(x ...int) (min int, maximum int) {
    minimum := -1
    max := 0    
    for _, v := range x {
        if minimum == -1 || v < minimum {
          minimum = v
        }
        if max < v {
            max = v
        }
    }
    return minimum, max 
}


Here we have defined a function which accepts a variable number of arguments of type int. The functions are called Variadic functions

Now we can call this function with a variable number of arguments, all of which should be of type int.

Here is how the whole thing looks like.

package main

import "fmt"

func main() {      
    minimum, maximum := calculateMinimumAndMaximum(48,96,86,68,
    57,82,63,70,
    37,34,83,27,
    19,97, 9,17,)
    fmt.Println("Minimum value is", minimum)
    fmt.Println("Maximum value is", maximum)   
}

func calculateMinimumAndMaximum(x ...int) (min int, maximum int) {
    minimum := -1
    max := 0    
    for _, v := range x {
        
        if minimum == -1 || v < minimum {
        
          minimum = v
        }
        
        if max < v {
         
            max = v
        }
    }
    return minimum, max 
}

~~ Whizdumb ~~

Working with functions in Golang

Follow the latest of Whizdumb’s journey here.

Functions are an integral part of any language, they help not just in building a functionality but also make the code cleaner, less buggy and easy to understand.

Lets explore a function in Go language, Here is a program which return the minimum of the given positive numbers

package main
import "fmt"
func main() {    
 x := []int{
    48,96,86,68,
    57,82,63,70,
    37,34,83,27,
    19,97, 9,17,
}    
    minimum := -1    
    for _, v := range x {
        
        if minimum == -1 || v < minimum {
        
          minimum = v
        }
    }
    fmt.Println(minimum)
}

We just used few functions here. main() is a function which gets invoked when we run this code. The main() like in C or Java forms the entry point from where the code starts executing.

We also used another function Println which is part of “fmt” package which we imported.

Now lets create our own function. Lets extract the logic to calculate the minimum out to another function and print it. Here is how it looks like

package main
import "fmt"

func main() {
    
 x := []int{
    48,96,86,68,
    57,82,63,70,
    37,34,83,27,
    19,97, 9,17,
}
  calculateMinimum(x)
}

func calculateMinimum(x []int) {
    minimum := -1
    for _, v := range x {
        
        if minimum == -1 || v < minimum {
        
          minimum = v
        }
    }
    fmt.Print(minimum)    
}

We have created a function called calculateMinimum() which accepts an array of integers and returns nothing.

Lets now modify it to return a value

package main
import "fmt"
func main() {
     x := []int{
    48,96,86,68,
    57,82,63,70,
    37,34,83,27,
    19,97, 9,17,
}
    minimum := calculateMinimum(x)
    fmt.Println("Minimum value is", minimum)
}

func calculateMinimum(x []int) int {
    minimum := -1
    for _, v := range x {
       if minimum == -1 || v < minimum {   
          minimum = v
        }
    }
    return minimum    
}

Here, notice the change in signature of the function from func calculateMinimum(x []int) to func calculateMinimum(x []int) int the extra int in the end tells the compiler that we are expecting an int value to be returned from this function.

We are assigning the returned value to minimum variable in the main function and using it to print the minimum value.

In the next blog we will see how we can return multiple values from a function.

Sd:
~~ Whizdumb ~~

Comparing two maps in Go

Follow the latest of Whizdumb’s journey here.

I have started learning Go these days, and have revived this blog and will be using it to share what all I learn in Go.

Lets start with looking at how we can compare two maps

package main

import "fmt"
import "reflect"
func main() {
var x map[int]int
var y map[int]int
x = make(map[int]int)
y = make(map[int]int)
x[1] = 10
y[1]=10
eq := reflect.DeepEqual(x, y)
if eq {
fmt.Println ("The two maps are equal")
}else{
fmt.Println ("The two maps are not equal")
}
}

In the above code to compare map, we have imported the reflect package, which provides a DeepEqual() method.

We have used reflect.DeepEqual(x,y) where x and y are two maps to be compared and we receive a boolean value as result. We have stored that boolean value in a new variable called eq.

In the above example two maps are equal. You can run the above code here.