douque9815
douque9815
2014-07-01 13:57

如何在控制台中打印结构变量?

  • struct
已采纳

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"`
}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

14条回答

  • duanpo7282 duanpo7282 7年前

    To print the name of the fields in a struct:

    fmt.Printf("%+v
    ", 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
    ", i,
            typeOfT.Field(i).Name, f.Type(), f.Interface())
    }
    
    点赞 评论 复制链接分享
  • dtr53557 dtr53557 3年前

    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.

    点赞 评论 复制链接分享
  • dongpengyu1363 dongpengyu1363 6年前

    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) ""
    }
    
    点赞 评论 复制链接分享
  • duanpu1111 duanpu1111 2年前

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

    点赞 评论 复制链接分享
  • dongyao4419 dongyao4419 3年前

    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
    ", data)
    

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

    点赞 评论 复制链接分享
  • dtkvlj5386 dtkvlj5386 3年前
    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)
    
    点赞 评论 复制链接分享
  • douxi6903 douxi6903 3年前

    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)
      }
    }
    
    点赞 评论 复制链接分享
  • dpbz14739 dpbz14739 3年前

    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.

    点赞 评论 复制链接分享
  • doumengxue7371 doumengxue7371 4年前

    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())
    }
    
    点赞 评论 复制链接分享
  • dsj8086 dsj8086 4年前
    p = Project{...}
    fmt.Printf("%+v", p)
    fmt.Printf("%#v", p) //with type
    
    点赞 评论 复制链接分享
  • douyoupingji7238 douyoupingji7238 5年前

    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
    ", a)))
    fmt.Printf("render.Render: %s
    ", 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)}
    
    点赞 评论 复制链接分享
  • dongtiran7769 dongtiran7769 4年前

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

    log.Println(
                strings.Replace(
                    fmt.Sprintf("%#v", post), ", ", "
    ", -1))
    
    点赞 评论 复制链接分享
  • doudian7996 doudian7996 4年前

    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
    ", o)
        }
    
    点赞 评论 复制链接分享
  • duanbiao4035 duanbiao4035 5年前

    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
    ", fieldName)
        }
    }
    
    /*
    Id
    Name
    Title
    */
    
    点赞 评论 复制链接分享