498
votes

How can I print (in 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"`
}
24
All of them, for debugging? Try fmt.Println.Ry-♦
I really like to use spew github.com/davecgh/go-spewRamakanth Reddy

24 Answers

845
votes

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())
}
168
votes

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) ""
}
140
votes

my 2cents would be to use json.MarshalIndent -- surprised this isn't suggested, as it is the most straightforward. for example:

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

no external deps and results in nicely formatted output.

29
votes

I think it would be better to implement a custom stringer if you want some kind of formatted output of a struct

for example

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)
    }

Happy Coding ;)

25
votes
p = Project{...}
fmt.Printf("%+v", p)
fmt.Printf("%#v", p) //with type
21
votes

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.

11
votes

I recommend to use Pretty Printer Library. In that you can print any struct very easily.

  1. Install Library

    https://github.com/kr/pretty

or

go get github.com/kr/pretty

Now do like this in your code

package main

import (
fmt
github.com/kr/pretty
)

func main(){

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

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

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

}

Also you can get difference between component through this library and so more. You can also have a look on library Docs here.

8
votes

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)
  }
}
5
votes

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

4
votes

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
*/
4
votes

To print the struct as JSON:

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

Also possible with (as it was mentioned above):

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

But the second option prints string values without "" so it is harder to read.

2
votes

Maybe this shouldn't be applied for production requests but if you are on debugging mode I suggest you follow the below approach.

marshalledText, _ := json.MarshalIndent(inputStruct, "", " ")
fmt.Println(string(marshalledText))

This results in formatting the data in json format with increased readability.

1
votes

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)}
1
votes
fmt.Printf("%+v\n", project)

This is the basic way of printing the details

0
votes

Another way is, create a func called toString that takes struct, format the fields as you wish.

import (
    "fmt"
)

type T struct {
    x, y string
}

func (r T) toString() string {
    return "Formate as u need :" + r.x + r.y
}

func main() {
    r1 := T{"csa", "ac"}
    fmt.Println("toStringed : ", r1.toString())
}
0
votes

Without using external libraries and with new line after each field:

log.Println(
            strings.Replace(
                fmt.Sprintf("%#v", post), ", ", "\n", -1))
0
votes

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

0
votes

package main

import "fmt"

type Project struct {
    Id int64 `json:"id"`
    Title string `json:"title"`
}

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

func main() {
    var instance Project
    Instance = Project{Id: 100, Title: "Print Struct"}
    fmt.Printf("%v\n", Instance)
}
0
votes

It is very convenient to use package fmt to output:

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

if you want to see the full type of the sturct, you can use # replace + :

fmt.Printf("%#v \n", yourProject) 
-1
votes
    type Response struct {
        UserId int    `json:"userId"`
        Id     int    `json:"id"`
        Title  string `json:"title"`
        Body   string `json:"body"`
    }

    func PostsGet() gin.HandlerFunc {
        return func(c *gin.Context) {
            xs, err := http.Get("https://jsonplaceholder.typicode.com/posts")
            if err != nil {
                log.Println("The HTTP request failed with error: ", err)
            }
            data, _ := ioutil.ReadAll(xs`enter code here`.Body)


            // this will print the struct in console            
            fmt.Println(string(data))


            // this is to send as response for the API
            bytes := []byte(string(data))
            var res []Response
            json.Unmarshal(bytes, &res)

            c.JSON(http.StatusOK, res)
        }
    }
-1
votes

If you want to print in console any type of struct, in Go you have an interface called Stringer:

type Stringer interface {
    String() string
}

And code for implementation would be:

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 (p Project) String() string {
    return fmt.Sprintf("ID:%s,Title:%s",p.Id,p.Title)
}

You can choose any Print strategy you want, and after just type:

p := &Project{Id:1,Title:"title"}
fmt.Println(p)
-1
votes

If you want to write in a log file, as I was searching previously. Then 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.

-4
votes

Most of these packages are relying on the reflect package to make such things possible.

enter image description here

fmt.Sprintf() is using -> func (p *pp) printArg(arg interface{}, verb rune) of standard lib

Go to line 638 -> https://golang.org/src/fmt/print.go

Reflection:

https://golang.org/pkg/reflect/

Example code:

https://github.com/donutloop/toolkit/blob/master/debugutil/prettysprint.go

-9
votes
fmt.Println("%+v", structure variable)

A better way to do this would be to create a global constant for the string "%+v" in a package called "commons"(maybe) and use it everywhere in your code

//In commons package
const STRUCTURE_DATA_FMT = "%+v"

//In your code everywhere
fmt.Println(commons.STRUCTURE_DATA_FMT, structure variable)