Sunday, August 30, 2015

Pass by Value vs. Pointers

When you call a function with parameters and pass an argument to it, Go by default pass the argument by copying it (i.e. pass by value). If you want to pass by reference use pointers. 

What does this mean?

For an Introduction to Pointers read Go Pointers

When an argument is passed by value, a function receiving a value will receive a copy of the original value and when you mutate (change) this value it will mutate the copy and not the original value. Let us see the following example:

Example RefCode# 1: Pass by Value

package main

import "fmt"

type Player struct {
 Name  string
 Score int
}

func currentScore(p Player) int {
 p.Score++
 return p.Score
}
func main() {
 arg := Player{Name: "Messi", Score: 101}
 fmt.Printf("%s just scored his %dth goal.\n", arg.Name, currentScore(arg))
 fmt.Printf("Now "+"%s has a total of %d goals.", arg.Name, arg.Score)
}

Output


Messi just scored his 102th goal.
Now Messi has a total of 101 goals.


Play with the above code

The intention of the above code is to show that Messi has just scored one more goal so total number of goals scored by him should become 101+1 i.e. 102. The second statement of the above code is wrong as it is still showing the old value (i.e. 101) in case of total number of goals scored! This has happened because we've changed the copy and not the original value!

See how the output differs when we pass the value by pointer instead of value. The following code shows the desired result:

Example RefCode# 2Pass by Pointer


package main

import "fmt"

type Player struct {
 Name  string
 Score int
}

func currentScore(p *Player) int {
 p.Score++
 return p.Score
}

func main() {
 arg := &Player{Name: "Messi", Score: 101}
 fmt.Printf("%s just scored his %dth goal.\n", arg.Name, currentScore(arg))
 fmt.Printf("Now "+"%s has a total of %d goals.", arg.Name, arg.Score)
}

Output
Messi just scored his 102th goal.
Now Messi has a total of 102 goals.

Play with the above code




What's the Difference Between RefCode# 1 & RefCode# 2?
The two code samples are same except the following 2 lines. Have a look and try to assimilate how pointer is used.

func currentScore(p Player) int {
vs.
func currentScore(p *Player) int {
----------------------------------------
arg := Player{Name: "Messi", Score: 101}
vs.
arg := &Player{Name: "Messi", Score: 101}
What are the Benefits of Pointers?

1. In contrast to the value type receiver, a pointer receiver is extremely lightweight (4 or 8 bytes) as only the pointer (a reference i.e. an address and not the actual value) is copied and not the entire value. 
2. you must use a pointer in cases where the argument value needs to be modified (like in the above example).
Official version from Go FAQs
I've copied and pasted it here for your reference [source]:
As in all languages in the C family, everything in Go is passed by value. That is, a function always gets a copy of the thing being passed, as if there were an assignment statement assigning the value to the parameter. For instance, passing an int value to a function makes a copy of the int, and passing a pointer value makes a copy of the pointer, but not the data it points to. Please share if you liked it.

Monday, August 17, 2015

Variadic - Functions with Variable Arguments

What are Variadic Functions?


A variadic function is one that can accept zero or more arguments for its last (or only) parameter. Such functions are indicated by placing an ellipsis (...) immediately before the type of the last or only parameter.

--Source: Programming in Go by Mark Summerfield.

Example: fmt.Println() is a variadic.


If you're a beginner, before you proceed, you can read my post about the Introduction of Functions in Go

An example is better than any explanation. See the following code sample and its output. In the code we've a function named classify that takes variable (arbitrary) number of string arguments (letters) and determines whether the letter is a vowel or consonant.

Note: Variadic functions receive the arguments as a slice of the type i.e. in below case it is string.


package main

import "fmt"

func classify(l ...string) {

 fmt.Println(l)

 for _, l := range l {

  switch l {

  case "A":
   fmt.Println("A vowel as in Apple")

  case "E":
   fmt.Println("E vowel as in Elephant")

  case "I":
   fmt.Println("I vowel as in Ice")

  case "O":
   fmt.Println("O vowel as in Ox")

  case "U":
   fmt.Println("U vowel as in Umbrella")

  case "Y":
   fmt.Println("Y as in Cry is a vowel. Y in Yellow is a consonant")

  default:
   fmt.Println(l + " consonant")

  }
 }

}

func main() {

 //Pass arbitrary number of string arguments
 classify("A", "B")
 classify("D", "E", "F")

       //Pass arbitrary number of arguments using Slices
 alphabet := []string{"A", "B", "C", "D", "E", "F", "G", "X", "Y", "Z"}
 alpha := alphabet[:2]

 classify(alpha...) //Note the way slice arg is passed using ...
 alphabet = alphabet[7:]
 classify(alphabet...)
}


Output





Please share if you liked this.

Sunday, August 16, 2015

Golang Interview Questions & Answers

These interview questions and answers are NOT intended to serve as a shortcut to intensive learning by self trying and assimilating the programming concepts of Go. Moreover, these questions are framed by me from my imagination while learning Go and not from any Go interview as such.

The sole purpose of these questions are to tickle your grey cells to make you think quickly and decisively in the right direction when you face challenges of daily rigors of Go programming. Also, for some of us, the Q and A format works well as far as learning is concerned, may be because in comparison to a  long paragraph, Q and A are specific in nature apart from being precise.  


Q# 1. Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”. 


An image of the expected output is shown here (only till 20 and not 100 as expected)




A# 1. Read this post for Answer

2. How many Looping constructs are present in Go programming language?

A# 2. Only one loop - for.

Q# 3. What is the default value of type bool in Go?

A# 3. false.

Q# 4. In case of Constants which type of expressions are evaluated at compile time and which are evaluated at run time?

A# 4. As a rule Constants are evaluated (determined) at compile time and never at run time. 

Q# 5. Which one of the following is correct?

         a. const Pi = 3.14

         b. const Pi = math.Pi 
         c. both a and b are correct
         d. None of the above

A# 5. c


Q# 6. Short  variable declaration := can be used only inside a function. True or False?

A# 6. True.

Q# 7. Short declaration := can be used for defining global variables. True or False?

A# 7. False.

Q# 8. What's wrong with the following code?

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

import "fmt"

func main() {

     var a int8 = 3

     var b int16 = 4

     sum := a + b
 
 fmt.Println(sum)
}


A# 8. Compile time error, you'll get the following message:
invalid operation: a + b (mismatched types int8 and int16)

Note - Though int8 and int16 are similar in nature they are two distinct types. One of the
 variables must be converted explicitly so that both the variables are of same type.

Q# 9. How can you rectify the above code?

A# 9. Replace line 11 with the following line.

          sum := a + int8(b)

Q# 10. What's the output of following code?

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

import "fmt"
 const ( 
       i = iota
       j 
       k 
 )
func main() {
 fmt.Println(i, j, k)
}

A# 10.

0 1 2
Q# 11. What's the output of following code?

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

import "fmt"
 const ( 
       i = 7
       j 
       k 
 )
func main() {
 fmt.Println(i, j, k)
}
A# 11
7 7 7
Q# 12. Refer code snippet Ref12A and Ref12B. They have the same output. True or False?

Ref12A:
package main

import "fmt"

const(
    p = iota  
    q = iota  
    r = iota        
)

func main() {
    fmt.Println(p, q, r)
}
Ref12B
package main

import "fmt"

const ( 
   p, q, r = iota, iota, iota 
)

func main() {
    fmt.Println(p, q, r)
}
A# 12. False.
Note: They have different outputs.
          Output of Ref12A
          0 1 2

          Output of Ref12B 
          0 0 0

Q# 13. What's the output of following code?

package main

import "fmt"

func main(){

     c := [...]int{} 

     fmt.Println(len(c))
 
}

A# 13 
    0

Note: Similarly, c := [...]int{4, 7, 2} would have given an output of 3. Remember, in an 
array declaration you've the option to replace length of the array with ... and Go run time
 is intelligent enough to compute the length at run time.

Q# 14. Arrays are value types i.e. in case of arrays as arguments, functions get their 
copies instead of a reference. True or False?

A# 14. True

Q# 15. Slices are reference type - the variable are stored in the heap? True or False?
A# 15. True
Q# 16. What's the output of following code?


package main

import "fmt"

func main() {
    
 oddSlc := []int{1,3,5,7}     
 evenSlc := []int{2,4,6,8}
 copy(evenSlc, oddSlc[2:])    
 fmt.Println("evenSlc = ", evenSlc)
}

A# 16. 
evenSlc =  [5 7 6 8]

Q# 17. Maps are value types. True or False?
A# 17. False

Note: Maps are Reference types. 
Q# 18. Is it recommended to use Global Variables in a program that implements G
routines?
A# 18. Global variables are not recommended as they may get accessed by multiple go routines (threads) concurrently that can easily lead to an unexpected behavior causing arbitrary results. 

Q# 19. Which of the following is NOT a valid Go identifier?

           a. _score2016
           b. 2016_Score
           c. गगन
          d. à¤—गनSky

P.S. Identifiers name program entities such as variables, functions, constants, 
structs, slices, maps etc.

A# 19.  b
Imp. NOTE: In Go the names of variable, function, constant, struct etc must begin with an Unicode letter or an underscore.
Q# 20. Is variable name iCount same as icount in Go programming?
A# 20. No. Go is case sensitive.


Q# 21. In idiomatic Go code package names are all in lower case. Do you agree?
A#  21. Yes. A few OS may not be able to handle mixed case names of packages.
Q# 22. renderHtml - is it an idiomatic Go variable name?

A# 22. No. renderHTML is a better choice. Andrew Gerrand suggestsAcronyms should be all capitals, as in ServeHTTP and IDProcessor.

Q# 23. In Go there's no concept of uninitialized variable. True or False?
A# 23. True
Q# 24. Which of the following is initial value (zero value) for interfaces, slice, pointers, 
maps, channels and functions?

                a. 0
                b. ""
                c. nil
                d. false

A# 24. c

Q# 25. A good name (say a variable name) in Go is short, consistent & easy to understand. Keeping this context in mind, do you agree with the following rule of thumb is Go:
The greater the distance between a name declaration & its uses, the longer the name
should be.

A# 25. Agree.

Q# 26. Is it True - Go compiler is bootstrapped - i.e. Go programming has been used to build Go compiler?

A# 26. Yes. Go 1.4 was used to build Go 1.5. As of Go 1.4 the Go compiler was writtem in C language.
Q# 27. What is the output of the following code snippet?
package main

import "fmt"

func main() {
 var i, j int
 fmt.Println(&i == &i, &i == &j, &j == nil)
}
A# 27. 

     true    false    false


Q# 28. What is the output of the following code snippet?
package main

import "fmt"

func main() {
 x := 1
 y := &x

 fmt.Println(*y)

 *y = 2
 fmt.Println(x)

}
A# 28. 
       1
       2
Q# 29. What is the output of the following code snippet?

package main

import "fmt"

func main() {

 x := 1
 incr(&x)
 fmt.Println(incr(&x))

}
func incr(p *int) int {
 *p++
 return *p
}

A# 29. 

          3

Q# 30. Arrays are homogeneous (their elements have same type) whereas Structs are heterogeneous. Is this Statement True?
 A# 30. Yes.

 
Q# 31. Arrays Structs are fixed size. In contrast Slices Maps are dynamic data structures that grow as values are added. Is this Statement True? 

 A# 31. Yes.


     
P.S. - This is a work in progress. Please contribute. Send your questions
to admin[at]techno-pulse[dot]com.


Wednesday, August 12, 2015

Go Functions with Multiple Return Values

Go functions support multiple return values. This feature is used for implementing error handling. 

For beginners recommended article before you proceed:

Introduction to Functions

Let us see a simple function that returns multiple values
[RefCode# 1]:


package main

import "fmt"

func multReturn() (int, string) {
 return 1, "OK"

}
func main() {
 fmt.Println(multReturn())
}


The output of the above code is:

1 OK

Play with the code here

In case you want to ignore one (or a few) of the values then you've the option to use blank identifier _ .
Run this code to understand the use of blank identifier. The same code is reproduced below for your reference.


[RefCode# 1.1]

package main

import "fmt"

func multReturn() (int, string) {
 return 1, "OK"

}
func main() {

 _, stringV := multReturn()
 fmt.Println(stringV)
}


Output

OK

Let us see another sample. [RefCode# 2]
Read the comments to understand it.

package main

import "fmt"

// Function is named swap 
//a, b, c are 3 parameters
// a is of type int, b, c are string
//The function returns int, string, string

func swap(a int, b, c string) (int, string, string) {
 return a, c, b // c is placed before b to swap

}
func main() {
 fmt.Println(swap(1, "Isaac", "Newton"))
 fmt.Println(swap(2, "Albert", "Einstein"))
}

The output of the above code:

1 Newton Isaac 2 Einstein Albert

Play with the code here

Multiple Returns for Error Handling

How can we use multiple return values for error handling? Let us see another example [RefCode# 3].


package main

import (
 "errors"
 "fmt"
)

func age(urAge int) (int, error) {

 if urAge > 120 || urAge < 0 {
  return -1, errors.New("Invalid age")
 } else {
  return urAge, nil
 }
}
func main() {

 if a, e := age(29); e != nil {
  fmt.Println("Error: ", e)
 } else {
  fmt.Println("Age: ", a)
 }
}

Output

Age: 29

Play with the code here

Note about the above code snippet [RefCode# 3]:

  • See import section - "errors"
  • errors.New is used to capture the given error message.
  • By convention, errors are the last return value and have type error, a built-in interface.
  • A nil value in the error position indicates that there was no error.Exercise

Write a program that receives age as an input from the user and returns a classification (such as infant, child, teenager, adult) based on the following conditions:

Age:

  • less than 0 - invalid
  • greater than 0 and less than or equal to 2 - infant
  • greater than 2 and less than or equal to 12 - Child
  • greater than 13 and less than or equal to 19 - Teenage
  • greater than 19 and less than or equal to 120 - Adult
  • greater than 120 - invalid

Solution [RefCode# 4]


package main
import (
 "errors"
 "fmt"
)
func age(urAge int) (string, error) {
    switch {
    case urAge < 0 || urAge > 120:
        return "", errors.New("Invalid age")
    case urAge <= 2:
        return "Infant", nil
    case urAge <= 12:
        return "Child", nil
    case urAge <= 19:
        return "Teenager", nil
    default:
        return "Adult", nil
    }
}
func main() {
    
    var input int
    fmt.Println("Enter your age: ")
    fmt.Scanf("%d", &input)

 if b, e := age(input); e != nil {
    fmt.Println("Error: ", e)
    } else {
    fmt.Println("Age: ", input)
    fmt.Println("Classification: ", b)
    }
}
Output
Did you like this? Please share your views.

Sunday, August 9, 2015

Go Methods

Prerequisites for this post:

You must understand Functions, Structs and Pointers. Please read the following posts before you proceed:

What are Methods?

Like functions, methods facilitate code reuse and are declared using func keyword. 

What is the difference between a Function and a Method?

A function with a receiver is a method. 

All methods are functions. But all functions might not be termed as methods.


package main

import "fmt"

type shape struct {
      l, w int
}

func (s shape) area() int { //value type receiver
      return s.l * s.w
}

func main() { 
 
     r := shape{11, 7}
     fmt.Println(r.area())
}

Play with the above code

In the above example the method area() is defined on the struct named shape. This might give you an impression that you can define a method only on struct. This is not true. You can define a method on any type you've defined in your package. However, you cannot define a method on a type from another package (including built in types).

Important: In the above code we have used (s shape) as a value type receiver.

Why is it better to have Pointer Receivers in Methods?


In Go, whenever we call a function that accepts an argument, the argument is copied to the function. Go passes everything by value. In the above example, the method named area() has value type shape as method receiver.


There are two specific reasons why a pointer receiver is recommended over a value type receiver.

1. With every method call the value is getting copied. Let us assume the struct contains many fields with large data sets. What happens if you're trying to copy this large struct? This is inefficient and the detrimental to code performance. In contrast to the value type receiver, a pointer receiver is extremely lightweight (4 or 8 bytes) as only the pointer (a reference i.e. an address) is copied and not the entire value. 

2. you must use a pointer in cases where a method can modify the value that its receiver points to.

Keeping the above discussion in mind, let us rewrite the above code using a pointer receiver:


package main

import "fmt"


type shape struct {
     l, w int
}

func (s *shape) area() int { //pointer receiver
     return s.l * s.w
}

func main() { 
 
   r := &shape{11, 7}
   fmt.Println(r.area())
}

Play with the above code

Why you must use pointer receiver?

In cases where the method doesn't modify the receiver value, we've a choice whether to define the method receiver as a value type or pointer. The experts recommend:

As a thumb rule, except for small structs and slices, always go for a pointer receiver, because it's great for performance.

Did this help you? If yes, feel free to share it.