758

How can I print (to the console) the Id, Title, Name, etc. of this struct in Golang?

type Project struct {
    Id      int64   `json:"project_id"`
    Title   string  `json:"title"`
    Name    string  `json:"name"`
    Data    Data    `json:"data"`
    Commits Commits `json:"commits"`
}
0

19 Answers 19

1281

To print the name of the fields in a struct:

fmt.Printf("%+v\n", yourProject)

From the fmt package:

when printing structs, the plus flag (%+v) adds field names

That supposes you have an instance of Project (in 'yourProject')

The article JSON and Go will give more details on how to retrieve the values from a JSON struct.


This Go by example page provides another technique:

type Response2 struct {
  Page   int      `json:"page"`
  Fruits []string `json:"fruits"`
}

res2D := &Response2{
    Page:   1,
    Fruits: []string{"apple", "peach", "pear"}}
res2B, _ := json.Marshal(res2D)
fmt.Println(string(res2B))

That would print:

{"page":1,"fruits":["apple","peach","pear"]}

If you don't have any instance, then you need to use reflection to display the name of the field of a given struct, as in this example.

type T struct {
    A int
    B string
}

t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()

for i := 0; i < s.NumField(); i++ {
    f := s.Field(i)
    fmt.Printf("%d: %s %s = %v\n", i,
        typeOfT.Field(i).Name, f.Type(), f.Interface())
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your answer but there is one more thing. My JSON files are related to an API... therefor I dont want to set the Id or Name, I just want to get it over the API and print it in console. How can I do that?
@fnr If you have a JSON document, you would need to unmarshall it, before being able to print its field.
Just a note, this works nicely with pointers as well. It won't print out the address, but it will add a & in front of your output.
222

I want to recommend go-spew, which according to their github "Implements a deep pretty printer for Go data structures to aid in debugging"

go get -u github.com/davecgh/go-spew/spew

usage example:

package main

import (
    "github.com/davecgh/go-spew/spew"
)

type Project struct {
    Id      int64  `json:"project_id"`
    Title   string `json:"title"`
    Name    string `json:"name"`
    Data    string `json:"data"`
    Commits string `json:"commits"`
}

func main() {

    o := Project{Name: "hello", Title: "world"}
    spew.Dump(o)
}

output:

(main.Project) {
 Id: (int64) 0,
 Title: (string) (len=5) "world",
 Name: (string) (len=5) "hello",
 Data: (string) "",
 Commits: (string) ""
}

Comments

218

Use json.MarshalIndent, as it is the most straightforward:

func prettyPrint(i interface{}) string {
    s, _ := json.MarshalIndent(i, "", "\t")
    return string(s)
}

no external deps and results in nicely formatted output.

7 Comments

👏🏻 Short and sweet. You can replace "\t" with " " if you want space indenting instead
Of note, Marshal() only serializes the exported fields of a struct -- it's perfect for maps though.
Definitely not a viable solution as non-exported fields AND exported fields with ignored JSON tag (i.e. json:"-") will not be included.
@GoForth define "viable" -- your comment is dismissive, assumes too much and in general not helpful; the OP did not include any constraints in his question: he provided a struct (all exported and tagged fields) and wanted to know how to print it. exactly how is the simple proposed code definitely not a viable solution to their query?
@mad.meesh By not viable I meant that while it works for OP's struct as all fields are exported and mapped to JSON, this solution is not a generally viable solution for all structs.
|
55

It would be better to implement a custom stringer if you want some kind of formatted output of a struct:

package main

    import "fmt"

    type Project struct {
        Id int64 `json:"project_id"`
        Title string `json:"title"`
        Name string `json:"name"`
    }

    func (p Project) String() string {
        return fmt.Sprintf("{Id:%d, Title:%s, Name:%s}", p.Id, p.Title, p.Name)
    }

    func main() {
        o := Project{Id: 4, Name: "hello", Title: "world"}
        fmt.Printf("%+v\n", o)
    }

1 Comment

Ah, yes. Thanks. I was looking for exactly this answer. This is far more idiomatic and perfectly aligned with Go's "object-orientation by interface signature". That way, you can easily change everything inside func (...) String() string and every library function expecting a string will work all the time without fuss. This is the way to do it in Go! (All other suggestions are obviously correct; they just use a more simple and straightforward way of printing structs; your suggestion, by contrast, would be the recommended way of exporting Project as part of a package.
29
p = Project{...}
fmt.Printf("%+v", p)
fmt.Printf("%#v", p) //with type

2 Comments

fmt.Printf(%#v, p) , throws me main.struct with struct type what is the difference between "%#v" and "%+v" @cokebol
"%+v" : This will give you the un-marshalled value along with their field-names. "%#v" : This will give the values along with their type/signatures. For eg: p := Project{Id: 4, Name: "hello", Title: "world"} output for "%+v": {Id:4 Title:world Name:hello} output for "%#v": main.Project{Id:4, Title:"world", Name:"hello"}
27

Alternatively, try using this function PrettyPrint()

// print the contents of the obj
func PrettyPrint(data interface{}) {
    var p []byte
    //    var err := error
    p, err := json.MarshalIndent(data, "", "\t")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("%s \n", p)
}

In order to use this you do not need any additional packages with the exception of fmt and encoding/json, just a reference, pointer to, or literal of the struct you have created.

To use just take your struct, initialize it in main or whatever package you are in and pass it into PrettyPrint().

type Prefix struct {
    Network string
    Mask    int
}

func valueStruct() {
    // struct as a value
    var nw Prefix
    nw.Network = "10.1.1.0"
    nw.Mask = 24
    fmt.Println("### struct as a pointer ###")
    PrettyPrint(&nw)
}

It's output would be

### struct as a pointer ###
{
    "Network": "10.1.1.0",
    "Mask": 24
} 

Play around with the code here.

Comments

23

I suggest you use fmt.Printf("%#v\n", s) , It will print golang type at the same time

package main

import (
    "fmt"
    "testing"
)

type student struct {
    id   int32
    name string
}

type Project struct {
    Id      int64   `json:"project_id"`
    Title   string  `json:"title"`
    Name    string  `json:"name"`
}

func TestPrint(t *testing.T) {
    s := Project{1, "title","jack"}
    fmt.Printf("%+v\n", s)
    fmt.Printf("%#v\n", s)
}

Result:

{Id:1 Title:title Name:jack}
main.Project{Id:1, Title:"title", Name:"jack"}

Comments

13

I recommend to use the Pretty Printer Library. With it, you can print any Go struct very easily.

package main

import (
    "fmt"

    "github.com/kr/pretty"
)

func main() {
    type Data []byte

    type Commits []string

    type Project struct {
        Id      int64   `json:"project_id"`
        Title   string  `json:"title"`
        Name    string  `json:"name"`
        Data    Data    `json:"data"`
        Commits Commits `json:"commits"`
    }

    myProject := Project{
        Id:      111672727,
        Title:   "My awesome project!",
        Name:    "To demo how `pretty` works",
        Data:    []byte("will work"),
        Commits: []string{"one commit", "two commits", "three commits"},
    }

    fmt.Printf("%# v\n", pretty.Formatter(myProject)) // It will print all struct details

    fmt.Printf("%# v\n", pretty.Formatter(myProject.Id)) // It will print component one by one.
}

Output

main.Project{
    Id:      111672727,
    Title:   "My awesome project!",
    Name:    "To demo how `pretty` works",
    Data:    {0x77, 0x69, 0x6c, 0x6c, 0x20, 0x77, 0x6f, 0x72, 0x6b},
    Commits: {"one commit", "two commits", "three commits"},
}
int64(111672727)

See the example above running on the Go Playground.

You can also get the difference between component through this library among several other things. Have a look at the library Docs.

2 Comments

Would be helpful to see the example of the output generated by pretty.Formatter
[deleted]
[deleted]
See go.dev/play/p/gpfER5OpnNs (updated version with newlines)
11

I like litter.

From their readme:

type Person struct {
  Name   string
  Age    int
  Parent *Person
}

litter.Dump(Person{
  Name:   "Bob",
  Age:    20,
  Parent: &Person{
    Name: "Jane",
    Age:  50,
  },
})

Sdump is pretty handy in tests:

func TestSearch(t *testing.T) {
  result := DoSearch()

  actual := litterOpts.Sdump(result)
  expected, err := ioutil.ReadFile("testdata.txt")
  if err != nil {
    // First run, write test data since it doesn't exist
        if !os.IsNotExist(err) {
      t.Error(err)
    }
    ioutil.Write("testdata.txt", actual, 0644)
    actual = expected
  }
  if expected != actual {
    t.Errorf("Expected %s, got %s", expected, actual)
  }
}

Comments

6

Sometimes, it might be handy to print the struct as valid Go code (the go/ast equivalent). For this purpose, https://github.com/hexops/valast does a great job:

package main

import (
    "fmt"

    "github.com/hexops/valast"
)

type ProjectData struct {
    Title   string `json:"title"`
    Name    string `json:"name"`
    Data    string `json:"data"`
    Commits string `json:"commits"`
}

type Project struct {
    Id   int64        `json:"project_id"`
    Data *ProjectData `json:"data"`
}

func main() {
    p := Project{
        Id: 1,
        Data: &ProjectData{
            Title:   "Test",
            Name:    "Mihai",
            Data:    "Some data",
            Commits: "Test Message",
        },
    }
    fmt.Println(valast.String(p))
}

Output:

go run main.go 
Project{Id: 1, Data: &ProjectData{
        Title:   "Test",
        Name:    "Mihai",
        Data:    "Some data",
        Commits: "Test Message",
}}

1 Comment

Sadly, it looks like go-spew hasn't received any updates in a long time. I believe it might have been abandoned. For now, it's still functional though.
5

When you have more complex structures, you might need to convert to JSON before printing:

// Convert structs to JSON.
data, err := json.Marshal(myComplexStruct)
fmt.Printf("%s\n", data)

Source: https://gist.github.com/tetsuok/4942960

Comments

3

Just use %+v with fmt.Printf

package main

import (
    "fmt"
)

type Project struct {
    Id      int64   `json:"project_id"`
    Title   string  `json:"title"`
    Name    string  `json:"name"`
    Data    Data    `json:"data"`
    Commits Commits `json:"commits"`
}

func main() {
    yourProject := Project{
        Id:    1,
        Title: "Project Title",
        Name:  "Project Name",
    }

    fmt.Printf("%+v\n", yourProject)
}

To have fine-grained control over the output format, like include or exclude fields and format them use this:

fmt.Printf("Id: %d, Title: %s, Name: %s\n", yourProject.Id, yourProject.Title, yourProject.Name)

docs: https://pkg.go.dev/fmt

Comments

2

Visit here to see the complete code. Here you will also find a link for an online terminal where the complete code can be run and the program represents how to extract structure's information(field's name their type & value). Below is the program snippet that only prints the field names.

package main

import "fmt"
import "reflect"

func main() {
    type Book struct {
        Id    int
        Name  string
        Title string
    }

    book := Book{1, "Let us C", "Enjoy programming with practice"}
    e := reflect.ValueOf(&book).Elem()

    for i := 0; i < e.NumField(); i++ {
        fieldName := e.Type().Field(i).Name
        fmt.Printf("%v\n", fieldName)
    }
}

/*
Id
Name
Title
*/

Comments

2

Here's an example demonstrating the use of format specifiers %d, %t, and %s for each built-in type in Go like: int, string, bool, struct, and interface.

package main

import "fmt"

// Define a struct
type Person struct {
    Name string
    Age  int
}

// Define an interface
type Describer interface {
    Describe() string
}

// Implement the Describer interface for Person
func (p Person) Describe() string {
    return fmt.Sprintf("Name: %s, Age: %d", p.Name, p.Age)
}

func main() {
    // Integer
    intVar := 42
    fmt.Printf("Integer %%d: %d\n", intVar)

    // Boolean
    boolVar := true
    fmt.Printf("Boolean %%t: %t\n", boolVar)

    // String
    strVar := "Hello, Go!"
    fmt.Printf("String %%s: %s\n", strVar)

    // Struct
    person := Person{Name: "Alice", Age: 30}
    fmt.Printf("Struct %%+v: %+v\n", person)

    // Interface
    var describer Describer
    describer = person
    fmt.Printf("Interface %%s: %s\n", describer.Describe())
}

In this example, each type is printed using the specified format specifiers.

%d is for integers

%t` is for booleans

%s` is for strings

%+v` is for structs, showing field names along with values

I hope it would be helpful for you. For more details, you can read this blog Exploring Built-in Types in Go

Comments

1

There's also go-render, which handles pointer recursion and lots of key sorting for string and int maps.

Installation:

go get github.com/luci/go-render/render

Example:

type customType int
type testStruct struct {
        S string
        V *map[string]int
        I interface{}
}

a := testStruct{
        S: "hello",
        V: &map[string]int{"foo": 0, "bar": 1},
        I: customType(42),
}

fmt.Println("Render test:")
fmt.Printf("fmt.Printf:    %#v\n", a)))
fmt.Printf("render.Render: %s\n", Render(a))

Which prints:

fmt.Printf:    render.testStruct{S:"hello", V:(*map[string]int)(0x600dd065), I:42}
render.Render: render.testStruct{S:"hello", V:(*map[string]int){"bar":1, "foo":0}, I:render.customType(42)}

Comments

1

I suggest to use json.Unmarshal()
I try to print the id with this:

var jsonString = `{"Id": 1, "Title": "the title", "Name": "the name","Data": "the data","Commits" : "the commits"}`
var jsonData = []byte(jsonString)

var data Project

var err = json.Unmarshal(jsonData, &data)
if err != nil {
    fmt.Println(err.Error())
    return
}

fmt.Println("Id :", data.Id)

Comments

0
u := User{ID: 1, Name: "Danilo", Email: "[email protected]"}

fmt.Println(u)
fmt.Printf("%+v\n", u)
b, _ := json.MarshalIndent(u, "", "  ")
fmt.Println(string(b))

// Best to utilized logrus it has logging severity
import log "github.com/sirupsen/logrus"
log.SetLevel(log.DebugLevel)
func main() {
    u := User{ID: 1, Name: "Danilo", Email: "[email protected]"}
    log.Debugf("User struct: %+v", u)
    log.WithFields(log.Fields{
        "id":    u.ID,
        "name":  u.Name,
        "email": u.Email,
    }).Info("User details")
}

Comments

-2

very simple I don't have the structure of Data and Commits So I changed the

package main

import (
    "fmt"
)

type Project struct {
    Id      int64   `json:"project_id"`
    Title   string  `json:"title"`
    Name    string  `json:"name"`
    Data    string  `json:"data"`
    Commits string  `json:"commits"`
}

func main() {
    p := Project{
    1,
    "First",
    "Ankit",
    "your data",
    "Commit message",
    }
    fmt.Println(p)
}

For learning you can take help from here : https://gobyexample.com/structs

Comments

-2

If you want to write in a log file, you should use:

log.Infof("Information %+v", structure)

Note: This will not work with log.Info or log.Debug. In this case, "%v" will get printed, and all the values of the structure will be printed without printing the key/variable name.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.