Wednesday, July 4, 2018

What it means to have an interface that has a dynamic type and dynamic value?


https://play.golang.org/p/1bT6HP54_fJ


Below code should explain when an interface seems nil but its not actually nil, because its dynamic type points to something concrete.


 ===== Code ====
package main

import (
"fmt"
"io"
"bytes"
)

func main() {
           // An interface which is nil.
var b io.Writer
fmt.Println(b==nil) // True

// An implementation of interface which is nil.
var bb *bytes.Buffer
fmt.Println(bb==nil) // True

// An interface whose dynamic type is concrete (*bytes.Buffer) and whose value is nil but holistically its not nil.
b = bb
fmt.Println(b==nil) // False and you would think its True
}


==== Output ====
true
true
false

Tuesday, October 3, 2017

Nil pointer passed to a function still points to nil after being changed in the function in Go (Golang)

Following from my previous post about everything being passed by value to a function, its time to think about the following scenario.
1. I create a function that takes a pointer which is pointing to nil.
2. I do something in the function such that pointer starts pointing to an object.
3. When I access the pointer outside the function (after the function has run) the pointer is still facing to nil. What the heck?

package main

import (
 "fmt"
)

type element struct {
 name string
}

func main() {
 var e *element
 NameIt(e, "gold")
 fmt.Println(e)        // Prints: 'nil'}

func NameIt(c_e *element, s string) {
 if c_e == nil {
  c_e = &element{name: s}
 }
 c_e.name = s
}

This is exactly due to the reason mentioned in my previous post. When the pointer 'e' is passed to the function 'NameIt', its pointing to 'nil'. The function creates a copy 'c_e' which is also pointing to 'nil' but then creates a new object of type 'element' and makes c_e point to the new element.

Note that the original pointer 'e' is still pointing to nil. The function returns and the original pointer 'e' has not changed. So what to do in cases where you want your passed pointer to behave as you expect. The following the correct way of doing it.
func main() {
 var e *element
 if e == nil {
  e = &element{}  // Ensure that you do not 
                  // pass nil pointers to a function.
 }
 NameIt(e, "gold")              // Prints '&{gold}'
 fmt.Println(e)
}

Always pass pointers that point to a valid reference than a 'nil', if you expect them to change later in a function.

Comments positive or negative are more than welcome.











Sunday, June 4, 2017

How does pass by value work in Go, when you pass pointers?

So have you also read that everything is passed by value in Go and thought then how come if a pointer is passed, the value pointed to by that pointer also changes?

Well this is how it works. Comments welcome!



Note the function change() returns the contents of the copied pointer only and the content is basically the address that its pointing to! Its pointing to the address of variable 'i'. So here we have two pointers pointing to the same variable with address (0x1040a124) but those two pointers have different addresses themselves (0x1040c118 and 0x1040c120).