Golang

Empty Struct

An empty struct in Go has no data elements.

type S struct{}

The most important property of the empty struct is that the width is zero. This allows to create a slice or channel of thousands of empty structs with a tiny memory footprint.

Here is a size comparison of the empty struct vs empty interface vs bool:

package main 
import (
"fmt"
"unsafe"
)

func main() {
var s struct{}
var i interface{}
var b bool
fmt.Println(unsafe.Sizeof(s), unsafe.Sizeof(i), unsafe.Sizeof(b))
}

On a 32 bit system: 0 8 1

On a 64-bit system:0 16 1null

Uses of empty struct

As a method receiver 

An empty struct{} can be used as a method receiver in cases when you don’t need data on a struct just methods with predefined input and output. E.g. You may want have a mock for testing interfaces.

An empty struct channel

An empty struct is very useful in channels when you have to notify that some event occurred but you don’t need to pass any information about it. Using a channel of  empty structure will only increment a counter in the channel but not assign memory, copy elements and so on. Using boolean values for this purpose has a memory footprint that can be avoided using the empty struct.

As a Set data type

Go has no Set data type. This can be easily emulated by using map[keyType]struct{}. This way map keeps only keys and no values.

Golang

Reflecting on structs

Reflection in Go allows  to manipulate objects and are most useful when dealing with structs.

I always wished I could range over a struct. But “range” only supports builtin types such as string, list, and map. Reflect makes it easy to do so.

I have a package that contains a function, I use frequently to do exactly this.  It takes in a struct and copies over the elements to a map so we can range over it.  https://github.com/mariadesouza/structutil

Here is a small example:

package main
import ( "fmt"
 "github.com/mariadesouza/structutil"
)
type testStruct struct { 
   Name       string 
   Email      []string 
   Occupation string
}
func main() {
  test := testStruct{"Ethan", []string{"emdesouza@gmail.com"}, "engineer"} 
  m := structutil.StructToMap(&test) 

  for key, val := range *m { 
    fmt.Println(key, ":", val)
  }
}

How it works?

Main concepts used:

type

Every variable in GO has a static type including elements of a struct.

interface{}

In go an interface{} represents an empty set of methods that satisfies all variable types

reflect

Go has a package called reflect that allows us to inspect the type and value stored in any data type.

I used reflect on a struct  and turn it into a map of names to values.  The call to ValueOf returns a Value representing the run-time data. This helps us to loop through the runtime elements

structmap := make(map[string]interface{}) // map to hold key - element
 elements := reflect.ValueOf(myStruct).Elem()  
 typeofT := elements.Type()    // type of Element
 for i := 0; i <elements.NumField(); i++ { 
     f := elements.Field(i) 
     elementName := typeofT.Field(i).Name //key name of element 
     valueOfElement := f.Interface() //returns current value as an interface{}
     structmap[elementName] = valueOfElement 
 } 

For this to work,  the struct elements have to be exported i.e. start with a capital or you will get a panic error as below.

panic: reflect.Value.Interface: cannot return value obtained from unexported field or method

https://play.golang.org/p/Kyn-k4rAFFX

Access private struct fields using reflection

We can read private struct variables in a package using reflection. However,  private field values cannot be changed.

E.g.

package main
import (
	"fmt"
	"reflect"
	"container/list"
)

func main() {
	cl := list.New()
        cl.PushFront(2)
	fieldvaluelen := reflect.ValueOf(cl).Elem().FieldByName("len")
	fmt.Println(fieldvaluelen.Int()) 
}

Output: 1

Reference

Laws of reflection