go-spew
Go-spew 为 Go 数据结构实现了一个非常漂亮的打印机,以帮助调试。 提供了一整套测试,具有100%的测试覆盖率,以确保正确的功能。 有关 gocov 覆盖率报告,请参见test cover .txt。Go-spew 是在自由ISC许可下获得许可的,因此它可以用于开源或商业项目。
如果您有兴趣阅读这个软件包是如何实现的,以及提供深度漂亮的打印机所涉及的一些挑战,那么这里有一篇关于它的博客文章。
文档
项目的完整 godoc 风格的文档可以在线查看,而不需要安装这个包,可以使用这里优秀的 GoDoc 站点:http://godoc.org/github.com/davecgh/go-spew/spew
安装包之后,您还可以使用 godoc 工具、通过运行 godoc -http=":6060",并将浏览器指向 http://localhost:6060/pkg/github.com/davecgh/go-spew/spew,即可在本地查看文档。
安装
$ go get -u github.com/davecgh/go-spew/spew
快速开始
将此导入行添加到您正在使用的文件中:
import "github.com/davecgh/go-spew/spew"
要转储具有完整换行、缩进、类型和指针信息的变量,请使用 dump、Fdump 或 Sdump:
spew.Dump(myVar1, myVar2, ...) spew.Fdump(someWriter, myVar1, myVar2, ...) str := spew.Sdump(myVar1, myVar2, ...)
或者,如果希望使用紧凑的内联打印样式的格式字符串,可以使用方便的包装器 Printf、Fprintf 等,其中包含 %v(最紧凑)、%+v(添加指针地址)、%#v(添加类型)或 %#+v(添加类型和指针地址):
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
调试 Web 应用程序示例
下面是一个如何使用 spew.Sdump() 来帮助调试 web 应用程序的示例。出于安全考虑,请确保使用 html.EscapeString() 函数包装输出。您还应该只在开发环境中使用这种调试技术,而不应该在生产环境中使用。
package main import ( "fmt" "html" "net/http" "github.com/davecgh/go-spew/spew" ) func handler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html") fmt.Fprintf(w, "Hi there, %s!", r.URL.Path[1:]) fmt.Fprintf(w, "<!--\n" + html.EscapeString(spew.Sdump(w)) + "\n-->") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }
Damp 输出样例
(main.Foo) { unexportedField: (*main.Bar)(0xf84002e210)({ flag: (main.Flag) flagTwo, data: (uintptr) <nil> }), ExportedField: (map[interface {}]interface {}) { (string) "one": (bool) true } } ([]uint8) { 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| 00000020 31 32 |12| }
Formatter 输出样例
指向 uint8 的双指针
%v: <**>5 %+v: <**>(0xf8400420d0->0xf8400420c8)5 %#v: (**uint8)5 %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
指向带有 uint8 字段和指向自身指针的循环结构的指针
%v: <*>{1 <*><shown>} %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>} %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>} %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
配置选项
spew 的配置由 ConfigState 类型中的字段处理。 为方便起见,所有顶级函数都使用 spew.Config global 提供的全局状态。
也可以创建一个 ConfigState 实例,该实例提供与顶级函数等效的方法。 这允许并发配置选项。 有关更多详细信息,请参阅 ConfigState 文档。
* Indent 用于转储函数的每个缩进级别的字符串。 默认情况下它是一个空格。一个流行的选择是“\t”。 * MaxDepth 下降到嵌套数据结构的最大级别数。 默认情况下没有限制。 * DisableMethods 禁用错误调用和Stringer接口方法。 默认情况下启用方法调用。 * DisablePointerMethods 禁用对仅接受来自非指针变量的指针接收器 的类型的错误和 Stringer 接口方法的调用。 此选项依赖于对不安全程序包的访问,因此 在无法访问不安全程序包(如Google App Engine) 或指定了“safe”构建标记的环境中运行时,它不会产生任何影响。 默认情况下启用指针方法调用。 * DisablePointerAddresses DisablePointerAddresses指定是否禁用打印 指针地址。在测试中区分数据结构时,这很有用。 * DisableCapacities DisableCapacities 指定是否禁用打印 arrays, slices, maps 和 channels。 在测试中区分数据结构时,这很有用。 * ContinueOnMethod 在调用错误和 Stringer 接口后启用递归到类型 方法。默认情况下禁用方法调用后的递归。 * SortKeys 指定映射键应在打印前进行排序。使用它 可以获得更确定的、可扩散的输出。请注意, 仅支持原生类型(bool,int,uint,float,uintptr 和 string) 以及实现错误或 Stringer 接口的类型,其他类型根据 reflect.Value.String()输出进行排序,以确保显示稳定性。 默认情况下使用自然映射顺序。 * SpewKeys SpewKeys 指出,作为最后的手段,map 键应该是 注入字符串并按这些字符串排序。这只是考虑 如果 SortKeys 为 true。
不安全的包依赖
此程序包依赖于不安全的程序包来执行某些更高级的功能,但它还支持“受限”模式,该模式允许它在不安全程序包不可用的环境中工作。 默认情况下,它将在 Google App Engine 上以此模式运行,并在使用 GopherJS 进行编译时运行。 还可以指定“安全”构建标记以强制包构建而不使用不安全的包。
许可
Go-spew 根据 copyfree ISC 许可证授权。
(First edition: vz edited at 2019.08.30)