Serialize structures in Golang

04 April, 2018

In this blogpost I'll show you one of the many ways to serialize structures in Go.

Data serialization

The serialization of data is simply a process of translating datatypes, structures (or objects in other languages) into a defined format as a byte stream, so they can be easily stored or transmitted with the intention to reconstruct it later.

I'll be using the easy and lightweight hprose serialization library (godoc), so be sure to

go get github.com/hprose/hprose-golang

The code

Make sure you import the library from hprose.

import "github.com/hprose/hprose-go"

In this example we'll be using the time package too.

Let's say we have the following structure that we want to serialize.

type Book struct {
	Name    string
	Pages   int
	Authors []string
	Release *time.Time
}

Lets create an instance of our type 'Book' and initialize some members with data. For example's sake we will be using a pointer to a time structure.

time := time.Now()
	
var SomeBook Book
SomeBook.Name = "Pirate tales"
SomeBook.Pages = 90
SomeBook.Authors = []string{"Peter", "John", "Wilma"}
SomeBook.Release = &time // Pointer to 'time'

Now serialize our 'SomeBook' with the hprose package.

Serialized, err := hprose.Serialize(SomeBook, true)
if err != nil {
	panic(err)
}

The 'hprose.Serialize()' function takes two arguments, the first one takes an interface (so all data types and structures you can think of), the second argument is a bool and should be true, not only is it faster but using false has no benefits for us.

Now the Serialized variable will hold a bytes array with the serialized data. If you were to print it as a string it would read the following.

c4"Book"4{s4"name"s5"pages"s7"authors"s7"release"}o0{s12"Pirate tales"i90;a3{s5"Peter"s4"John"s5"Wilma"}D20180404T233150.084574;}

As you may noticed, the pointer to the 'time' structure gets dereferenced and packed like a structured member, not the actual memory address which it points to.

Now let us unserialize the data.

var NewBook Book
err = hprose.Unserialize(Serialized, &NewBook, true)
if err != nil {
	panic(err)
}

Full code example

package main

import (
	"github.com/hprose/hprose-go"
	"time"
)

type Book struct {
	Name    string
	Pages   int
	Authors []string
	Release *time.Time
}

func main() {
	time := time.Now()

	var SomeBook Book
	SomeBook.Name = "Pirate tales"
	SomeBook.Pages = 90
	SomeBook.Authors = []string{"Peter", "John", "Wilma"}
	SomeBook.Release = &time // Pointer to 'time'

	Serialized, err := hprose.Serialize(SomeBook, true)
	if err != nil {
		panic(err)
	}

	var NewBook Book
	err = hprose.Unserialize(Serialized, &NewBook, true)
	if err != nil {
		panic(err)
	}
}