json: cannot unmarshal object into Go struct field

Problem

json: cannot unmarshal object into Go struct field

Code

package main

import (
	"encoding/json"
	"fmt"
)

// DTO object
type mould struct {
	Particle tiny
}

type tiny interface {
	GetName() string
}

// Implement the interface
type speck struct {
	Name string `json:"name"`
}

func (s *speck) GetName() string {
	return s.Name
}

// Constructor
func NewSpeck(name string) tiny {
	return &speck{
		Name: name,
	}
}

//
func main() {
	dirt := NewSpeck("space")

	brown := &mould{}
	brown.Particle = dirt
	brownBytes, err := json.Marshal(brown)

	if err != nil {
		panic("marshal error")
	}

	brownLike := &mould{} // unmarshal has no "idea" of how to unpack!
	err = json.Unmarshal(brownBytes, &brownLike)
	if err != nil {
		panic("unmarshal err=%+v\n", err)
		return
	}
}

Go Playground Link

The error is:

go run unmarshal_interface.go
panic: json: cannot unmarshal object into Go struct field mould.Particle of type main.tiny

The problem with code is the inability of Go runtime to get target struct for unmarshaling.

Unmarshal essentially copies the byte array to a struct type. However, in the case of the unmarshal of the type tiny, runtime could not find any destination struct. The interface in Go just has behavior, not types.

Solutions

  1. Easy! Don’t return interface in a function. 🙂
  2. Help the runtime and add some info on destination struct.
    // solution
    brownLike2 := &mould{}
    brownLike2.Particle = &speck{} // Now unmarshal "knows" how to unpack the byte array!
    
    err = json.Unmarshal(brownBytes, &brownLike2)
    fmt.Printf("brownLike2=%#v err=%+v\n", brownLike2.Particle.GetName(), err)
    

Refernces

Written with StackEdit.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: