使用Golang打印可读的变量

27

如何以易读的方式打印地图、结构体或其他内容?

使用 PHP,您可以这样做。

echo '<pre>';
print_r($var);
echo '</pre>';
或者
header('content-type: text/plain');
print_r($var);

如果你正在生成HTML,请不要使用显式的Fprintf()语句,除非你真的知道自己在做什么。请优先使用html/template,它可以进行适当的转义处理。你上面编写的代码容易受到简单的注入攻击。别这样做。 :P - dyoo
6个回答

20

使用Go语言的fmt包。例如,

package main

import "fmt"

func main() {
    variable := "var"
    fmt.Println(variable)
    fmt.Printf("%#v\n", variable)
    header := map[string]string{"content-type": "text/plain"}
    fmt.Println(header)
    fmt.Printf("%#v\n", header)
}

输出:

var
"var"
map[content-type:text/plain]
map[string]string{"content-type":"text/plain"}

Package fmt

import "fmt" 

Overview

Package fmt implements formatted I/O with functions analogous to C's printf and scanf. The format 'verbs' are derived from C's but are simpler.


5
最好的做法是您的示例代码也展示出%+v%v - AndrewN

16

我认为在很多情况下,使用"%v"就足够简洁了:

fmt.Printf("%v", myVar)

来自 fmt 包文档页面:

%v 以默认格式打印值。 当打印结构体时,加号标志 (%+v) 添加字段名称。

%#v 以 Go 语法表示值。

这里是一个例子:

package main

import "fmt"

func main() {
    // Define a struct, slice and map
    type Employee struct {
        id   int
        name string
        age  int
    }
    var eSlice []Employee
    var eMap map[int]Employee

    e1 := Employee{1, "Alex", 20}
    e2 := Employee{2, "Jack", 30}
    fmt.Printf("%v\n", e1)
    // output: {1 Alex 20}
    fmt.Printf("%+v\n", e1)
    // output: {id:1 name:Alex age:20}
    fmt.Printf("%#v\n", e1)
    // output: main.Employee{id:1, name:"Alex", age:20}

    eSlice = append(eSlice, e1, e2)
    fmt.Printf("%v\n", eSlice)
    // output: [{1 Alex 20} {2 Jack 30}]
    fmt.Printf("%#v\n", eSlice)
    // output: []main.Employee{main.Employee{id:1, name:"Alex", age:20}, main.Employee{id:2, name:"Jack", age:30}}

    eMap = make(map[int]Employee)
    eMap[1] = e1
    eMap[2] = e2
    fmt.Printf("%v\n", eMap)
    // output: map[1:{1 Alex 20} 2:{2 Jack 30}]
    fmt.Printf("%#v\n", eMap)
    // output: map[int]main.Employee{1:main.Employee{id:1, name:"Alex", age:20}, 2:main.Employee{id:2, name:"Jack", age:30}}
}

5
您可以使用fmt.Println()进行打印。您需要导入“fmt”包(请参见下面的示例)。许多数据类型可以直接打印输出。如果想要为自定义类型获取易于阅读的打印输出,则需要为该类型定义String() string方法。
要尝试以下示例,请单击这里:http://play.golang.org/p/M6_KnRJ3Da
package main

import "fmt"

// No `String()` method
type UnstringablePerson struct {
    Age int
    Name string
}

// Has a `String()` method
type StringablePerson struct {
    Age int
    Name string
}

// Let's define a String() method for StringablePerson, so any instances
// of StringablePerson can be printed how we like
func (p *StringablePerson) String() string {
    return fmt.Sprintf("%s, age %d", p.Name, p.Age)
}

func main() {
    // Bobby's type is UnstringablePerson; there is no String() method
    // defined for this type, so his printout will not be very friendly
    bobby := &UnstringablePerson{
        Age: 10,
        Name: "Bobby",
    }

    // Ralph's type is StringablePerson; there *is* a String() method
    // defined for this type, so his printout *will* be very friendly
    ralph := &StringablePerson{
        Age: 12,
        Name: "Ralph",
    }
    fmt.Println(bobby) // prints: &{10 Bobby}
    fmt.Println(ralph) // prints: Ralph, age 12
}

3

2
fmt.Printf("%v", whatever) 

在Go语言中,%v类似于PHP中的print_r()、var_dump()和var_export()函数。(%v是重要的一部分)。

祝你好运!


1

我用这个来调试:

func printVars(w io.Writer, writePre bool, vars ...interface{}) {
    if writePre {
        io.WriteString(w, "<pre>\n")
    }
    for i, v := range vars {
        fmt.Fprintf(w, "» item %d type %T:\n", i, v)
        j, err := json.MarshalIndent(v, "", "    ")
        switch {
        case err != nil:
            fmt.Fprintf(w, "error: %v", err)
        case len(j) < 3: // {}, empty struct maybe or empty string, usually mean unexported struct fields
            w.Write([]byte(html.EscapeString(fmt.Sprintf("%+v", v))))
        default:
            w.Write(j)
        }
        w.Write([]byte("\n\n"))
    }
    if writePre {
        io.WriteString(w, "</pre>\n")
    }
}

游乐场


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