Go: How to pretty print nested objects with pointers values?

Issue

How can I pretty print the object below?

package main

// OBJECT: {
//   TABLE: {
//     files: [],
//     data: {
//        CODE: {
//          name: "NAME",
//          count: 123,
//       }
//     }
//
// }

import (
    "encoding/json"
    "fmt"
    "log"
)

type Container map[string]*Table

type Table struct {
    files []string
    data  map[string]*Data
}

type Data struct {
    name  string
    count int
}

func main() {

    object := Container{
        "table1": {
            files: []string{"file-1.1"},
            data: map[string]*Data{
                "XYZ": {
                    name:  "foo",
                    count: 123,
                },
            },
        },
        "table2": {
            files: []string{
                "file-2.1",
                "file-2.2",
                "file-2.3",
            },
        },
        "table3": {files: []string{"file-3.1"}},
    }

    fmt.Printf("%#v\n", &object)
    objectJSON, err := json.MarshalIndent(object, "", "  ")
    if err != nil {
        log.Fatalf(err.Error())
    }
    fmt.Printf("%s\n", objectJSON)

}

https://go.dev/play/p/FRWZsfwgyNU

With this code, I’m only getting the first depth of my object:

&main.Container{"table1":(*main.Table)(0xc00005c020), "table2":(*main.Table)(0xc00005c040), "table3":(*main.Table)(0xc00005c060)}
{
  "table1": {},
  "table2": {},
  "table3": {}
}

Program exited.

Solution

This isn’t about "depth". You can’t generically pretty-print private, un-exported fields using fmt.Printf or json.Marshal. If you want the variable to appear when marshling, export them (ie, change Table.files to Table.Files. Go will marshal exported fields to arbitrary depth:

{
  "foo1": {
    "Files": [
      "file-1.1"
    ],
    "Data": {
      "XYZ": {
        "Name": "foo",
        "Count": 123
      }
    }
  },
  "foo2": {
    "Files": [
      "file-2.1",
      "file-2.2",
      "file-2.3"
    ],
    "Data": null
  },
  "foo3": {
    "Files": [
      "file-3.1"
    ],
    "Data": null
  }
}

If you want to pretty print the object using fmt.Printf("%v", ...) then you need to implement the Stringer interface on each of your class. At that point, the decision about how to print the object is entirely up to you and you can include public or private members in whatever format you’d like.

Answered By – user229044

Answer Checked By – Mildred Charles (GoLangFix Admin)

Leave a Reply

Your email address will not be published.