如何漂亮地打印变量

64

Go 中是否有类似 Ruby 的 awesome_print

例如,在 Ruby 中你可以写:

require 'ap'
x = {a:1,b:2} // also works for class
ap x

输出将是:

{ 
  "a" => 1,
  "b" => 2
}

我找到的最接近的东西是Printf("%#v", x)


2
如果可以接受外部包,考虑使用 pretty - Mark
3
我喜欢 go-spew - Dmitri Goldring
我尝试了go-spew和pretty两种工具,发现当嵌套结构体深度较大时,pretty会失去美观感而go-spew则可以保持。 - ufukty
5个回答

124

如果你的目标是避免引入第三方包,那么你的另一个选择是使用json.MarshalIndent

x := map[string]interface{}{"a": 1, "b": 2}
b, err := json.MarshalIndent(x, "", "  ")
if err != nil {
    fmt.Println("error:", err)
}
fmt.Print(string(b))

输出:

{
    "a": 1,
    "b": 2
}

示例代码:http://play.golang.org/p/SNdn7DsBjy


1
测试多层缩进。https://play.golang.org/p/d3nO4Rht90 - Xeoncross
1
当存在自定义结构体(不支持的类型错误)时,Marshal 会遇到麻烦。有什么简单的方法可以解决这个问题吗? - etang
@etang 你需要给我展示一个简单的例子,这样我才能给你更好的答案(也许在 Playground 中展示?)。如果类型变得复杂,我想你可能需要实现 JSON 包接口之一来进行取消编组。 - Simon Whitehead

27

没事了,我找到了一个:https://github.com/davecgh/go-spew

// import "github.com/davecgh/go-spew/spew"
x := map[string]interface{}{"a":1,"b":2}
spew.Dump(x)

会输出:

(map[string]interface {}) (len=2) {
 (string) (len=1) "a": (int) 1,
 (string) (len=1) "b": (int) 2
}

16

1
漂亮输出的好方法 - Krishna ps

4

我刚刚根据Simon的答案编写了一个简单的函数:

func dump(data interface{}){
    b,_:=json.MarshalIndent(data, "", "  ")
    fmt.Print(string(b))
}

我经常这样做,+1。虽然通常在出现错误时我会感到恐慌。 - erik258

3

我想使用这样的代码片段:

func printMap(m map[string]string) {
    var maxLenKey int
    for k, _ := range m {
        if len(k) > maxLenKey {
            maxLenKey = len(k)
        }
    }

    for k, v := range m {
        fmt.Println(k + ": " + strings.Repeat(" ", maxLenKey - len(k)) + v)
    }
}

输出结果将会是这样的:
short_key:       value1
really_long_key: value2

告诉我,是否有更简单的方法来完成相同的对齐。

5
您可以使用 fmt.Printf("%*s: %s", maxLenKey, k, v) 来避免调用 strings.Repeat 和所有的字符串连接操作。 - Eric Lindsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接