liveBook · Manning

Deserialization

As explained in Go in Practice, Second Edition

Unmarshaling is the process of converting a serialized representation into in-memory data structures.

Deserialization, also called unmarshaling, turns serialized data into in-memory values. In Go, a practical starting point is a configuration file: define a struct that matches the data, decode into it at startup, and check the returned error before using its fields. section 2.2.1

Listing 2.9 Parsing a JSON configuration file: json_config.go
package main

import (
     "encoding/json"
     "fmt"
     "os"
)
type configuration struct {     #1
     Enabled bool               #1
     Path    string             #1
}                               #1
func main() {
     file, err := os.Open("config.json")     #2
     if err != nil {
         panic(err)
     }
     defer file.Close()
     decoder := json.NewDecoder(file)      #3
     conf := configuration{}               #3
     err = decoder.Decode(&conf)           #3
     if err != nil {
            fmt.Println("Error:", err)
     }
     fmt.Println(conf.Path)
}

A JSON configuration parser opens a file, passes it to json.NewDecoder, and calls Decode with a pointer to the destination struct. section 2.2.1

Fields that another package must populate need uppercase initial letters. Match the struct’s names and nesting to the JSON representation; otherwise, parts of the configuration may not be populated as intended. The decoded values are then available through the struct instance. section 2.2.1

Choose the decoding path to fit the format and workload:

  • For a JSON configuration file, use the standard library’s encoding/json decoder and a matching struct. section 2.2.1
  • For repeatedly decoded REST JSON, consider generated codec code. Unlike encoding/json’s reflection-based path, generated code avoids repeated type inspection and can reduce execution and allocation costs. section 12.3.1
  • For a custom key-value format, write Unmarshal(data []byte, v interface{}) error and use reflection to connect input names to tagged struct fields. section 13.2.3
Listing 12.8 Decoding JSON into an instance of a type
var u2 user.User  #1
err = codec.NewDecoderBytes(out, jh).Decode(&u2)  #2
if err != nil {
     …
}
fmt.Println(u2)  #3

The codec decoder takes JSON bytes and a destination pointer, then populates a typed value. Its surrounding example uses a struct with codec tags and generated code. section 12.3.1

A custom INI-like decoder can scan the input line by line, split each valid line at its first equals sign, and pass the name and value to a field-setting helper. The helper matches names against ini tags and converts supported field types. This example is deliberately limited to structs and skips malformed lines; it is a pattern to adapt, not a general-purpose format parser. section 13.2.3

Listing 13.15 The Unmarshal function
func Unmarshal(data []byte, v interface{}) error {
     val := reflect.Indirect(reflect.ValueOf(v))   #1
     t := val.Type()
     b := bytes.NewBuffer(data)
     scanner := bufio.NewScanner(b)    #2
     for scanner.Scan() {              #2
            line := scanner.Text()     #2
            pair := strings.SplitN(line, "=", 2)   #3
            if len(pair) < 2 {
                   // Skip any malformed lines.
                   continue
            }
            setField(pair[0], pair[1], t, val)   #4
     }
     return nil
}

The Unmarshal implementation shows the scanner, first-equals-sign split, and handoff to setField. section 13.2.3

Round-trip a tagged struct

A Processes struct uses ini tags such as `ini:"total"` and `ini:"load"`. Marshal produces key-value lines; Unmarshal reads those bytes into a new Processes value, demonstrating that the field mapping works in both directions. section 13.2.3

How Go in Practice, Second Edition covers it

How deep it goes
Works from JSON file decoding through a reflection-based INI Unmarshal; the custom implementation is limited to structs and supported field kinds.
Examples
Uses JSON bytes decoded into a typed value and a tagged Processes struct reconstructed from key-value lines.
What it assumes
Assumes basic Go structs, pointers, files, and error handling; introduces tag inspection and reflection while constructing a custom decoder.
What you can do after
Build it from scratch for tagged INI structs or apply encoding/json to load configuration into a Go struct.
How it connects
Links struct tags, reflection, marshaling, code generation, and REST JSON performance to decoding choices.

Also explained in

Compare how 10 books explain deserialization →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Practice, Second Edition. The section links point to the parts of the book it draws on.