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

问题描述 投票:0回答:18

如何在 Golang 中打印(到控制台)该结构的

Id
Title
Name
等?

type Project struct {
    Id      int64   `json:"project_id"`
    Title   string  `json:"title"`
    Name    string  `json:"name"`
    Data    Data    `json:"data"`
    Commits Commits `json:"commits"`
}
struct go
18个回答
1205
投票

打印结构体中字段的名称:

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

来自

fmt

打印结构时,加号标志 (

%+v
) 添加字段名称

假设您有一个 Project 实例(在“

yourProject
”中)

文章 JSON 和 Go 将提供有关如何从 JSON 结构检索值的更多详细信息。


这个通过示例页面提供了另一种技术:

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

将打印:

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

如果您没有任何实例,那么您需要使用反射来显示给定结构体的字段名称,如本示例中所示

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

214
投票

我想推荐 go-spew,根据他们的 github “为 Go 数据结构实现一个深度漂亮的打印机以帮助调试”

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

使用示例:

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

输出:

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

203
投票

我的 2 美分是使用

json.MarshalIndent
- 很惊讶没有建议这样做,因为它是最简单的。例如:

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

无需外部依赖,即可获得格式良好的输出。


52
投票

我认为如果您想要某种

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

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

27
投票

或者,尝试使用此功能

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

为了使用它,除了

fmt
encoding/json
之外,您不需要任何其他包,只需引用、指向您创建的结构体的指针或文字即可。

要使用,只需获取您的结构,在 main 或您所在的任何包中初始化它,然后将其传递到

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

它的输出是

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

使用代码这里


17
投票

我建议你使用

fmt.Printf("%#v\n", s)
,它会同时打印golang类型

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

结果:

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

11
投票

我建议使用Pretty Printer Library。这样您就可以非常轻松地打印任何结构。

  1. 安装库

    https://github.com/kr/pretty

go get github.com/kr/pretty

现在在你的代码中这样做

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.

}

您还可以通过这个库了解组件之间的差异等等。您还可以在此处查看库Docs


10
投票

我喜欢垃圾

来自他们的自述文件:

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

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

Sdump
在测试中非常方便:

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

6
投票

有时,将结构打印为有效的 Go 代码(相当于

go/ast
)可能会很方便。为此,https://github.com/hexops/valast做得很好:

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

输出:

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

5
投票

当您有更复杂的结构时,您可能需要在打印之前转换为 JSON:

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

来源:https://gist.github.com/tetsuok/4942960


3
投票

访问这里查看完整代码。在这里您还可以找到在线终端的链接,可以在其中运行完整的代码,并且该程序表示如何提取结构的信息(字段的名称、类型和值)。下面是仅打印字段名称的程序片段。

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

2
投票

这里有一个示例,演示了 Go 中每个内置类型的格式说明符

%d
%t
%s
的使用,例如:
int
string
bool
struct
 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())
}

在此示例中,使用指定的格式说明符打印每种类型。

%d is for integers

%t` is for booleans

%s` is for strings

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

希望对您有帮助。有关更多详细信息,您可以阅读此博客探索 Go 中的内置类型


1
投票

还有 go-render,它处理指针递归以及字符串和 int 映射的大量键排序。

安装:

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

示例:

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

哪个打印:

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
投票

我建议使用

json.Unmarshal()
我尝试打印 ID,希望有帮助:

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)

0
投票

只需将

%+v
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)
}

要对输出格式进行细粒度控制,例如包含或排除字段并格式化它们,请使用以下命令:

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

文档:https://pkg.go.dev/fmt


-1
投票

非常简单 我没有数据和提交的结构所以我改变了

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

为了学习,您可以从这里获取帮助:https://gobyexample.com/structs


-1
投票

如果您想写入日志文件,正如我之前搜索的那样。那么你应该使用:

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

注意::这不适用于 log.Info 或 log.Debug。在这种情况下,将打印“%v”,并且将打印结构体的所有值,而不打印键/变量名称。

© www.soinside.com 2019 - 2024. All rights reserved.