fnr
fnr

Reputation: 9657

How to print struct variables in console?

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"`
}

Upvotes: 748

Views: 809698

Answers (18)

Vinicius Cardoso
Vinicius Cardoso

Reputation: 1086

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

Upvotes: 2

Md Kamruzzaman
Md Kamruzzaman

Reputation: 394

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

Upvotes: 2

刘孟德
刘孟德

Reputation: 231

I suggest u 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"}

Upvotes: 22

Friska S E Putri
Friska S E Putri

Reputation: 43

i suggest to use json.Unmarshal() i try to print the id with this hope its helpfull:

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)

Upvotes: 1

Vivek Maru
Vivek Maru

Reputation: 8499

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

Upvotes: 53

Mihai Todor
Mihai Todor

Reputation: 8239

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",
}}

Upvotes: 6

Ayush
Ayush

Reputation: 406

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.

Upvotes: -1

Ankit Malik
Ankit Malik

Reputation: 1

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

Upvotes: -1

VonC
VonC

Reputation: 1323035

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

Upvotes: 1258

Erik Toor
Erik Toor

Reputation: 552

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.

Upvotes: 27

Cassio
Cassio

Reputation: 1547

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

Upvotes: 5

amku91
amku91

Reputation: 1038

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.

Upvotes: 12

mad.meesh
mad.meesh

Reputation: 2766

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.

Upvotes: 214

qed
qed

Reputation: 23094

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

Upvotes: 11

cokeboL
cokeboL

Reputation: 307

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

Upvotes: 29

hygull
hygull

Reputation: 8740

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

Upvotes: 3

Michael Whatcott
Michael Whatcott

Reputation: 5955

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

Upvotes: 1

Martin Olika
Martin Olika

Reputation: 2331

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

Upvotes: 219

Related Questions