調試利器 go-spew
對於應用的調試,我們經常會使用 fmt.Println 來輸出關鍵變量的數據。或者使用 log 庫,將數據以 log 的形式輸出。對於基礎數據類型,上面兩種方法都可以比較方便地滿足需求。對於一些結構體類型數據,通常我們可以先將其序列化後再輸出。
如果結構體中包含不可序列化的字段,比如 func 類型,那麼序列化就會拋出錯誤,阻礙調試。
go-spew
上面的需求,go-spew 可以完美地幫我們實現。go-spew 可以以一種非常友好的方式輸出完整的數據結構信息。如:
s := "GoCN"
i := 123
spew.Dump(s, i)
//-----
(string) (len=4) "GoCN"
(int) 123
對於複雜的數據類型:
type S struct {
S2 *S2
I *int
}
type S2 struct {
Str string
}
func main() {
s := "GoCN"
i := 2
f := []float64{1.1, 2.2}
m := map[string]int{"a": 1, "b": 2}
e := errors.New("new error")
ss := S{S2: &S2{Str: "xxx"}, I: &i}
spew.Dump(s, i, f, m, e, ss)
}
//-----
(string) (len=4) "GoCN"
(int) 2
([]float64) (len=2 cap=2) {
(float64) 1.1,
(float64) 2.2
}
(map[string]int) (len=2) {
(string) (len=1) "a": (int) 1,
(string) (len=1) "b": (int) 2
}
(*errors.errorString)(0xc000010320)(new error)
(main.S) {
S2: (*main.S2)(0xc000010330)({
Str: (string) (len=3) "xxx"
}),
I: (*int)(0xc00001e1f0)(2)
}
可以看到,對於 map、slice、嵌套 struct 等類型的數據都可以友好地展示出來。包括長度、字段類型、字段值、指針值以及指針指向的數據等。
u := &url.URL{Scheme: "https", Host: "gocn.vip"}
req, err := http.NewRequestWithContext(context.Background(), "GET", u.String(), nil)
if err != nil {
panic(err)
}
spew.Dump(req)
//-----
(*http.Request)(0xc000162000)({
Method: (string) (len=3) "GET",
URL: (*url.URL)(0xc000136090)(https://gocn.vip),
Proto: (string) (len=8) "HTTP/1.1",
ProtoMajor: (int) 1,
ProtoMinor: (int) 1,
Header: (http.Header) {
},
Body: (io.ReadCloser) <nil>,
GetBody: (func() (io.ReadCloser, error)) <nil>,
ContentLength: (int64) 0,
TransferEncoding: ([]string) <nil>,
Close: (bool) false,
Host: (string) (len=8) "gocn.vip",
Form: (url.Values) <nil>,
PostForm: (url.Values) <nil>,
MultipartForm: (*multipart.Form)(<nil>),
Trailer: (http.Header) <nil>,
RemoteAddr: (string) "",
RequestURI: (string) "",
TLS: (*tls.ConnectionState)(<nil>),
Cancel: (<-chan struct {}) <nil>,
Response: (*http.Response)(<nil>),
ctx: (*context.emptyCtx)(0xc000020090)(context.Background)
})
上面是一個 http.Request 類型的變量,其中包含多種複雜的數據類型,但 go-spew 都可以友好地輸出出來,非常方便我們調試。
Dump 系列函數
go-spew 有三個 Dump 系列函數:
-
Dump() 標準輸出到 os.Stdout
-
Fdump() 允許輸出自定義 io.Writer
-
Sdump() 輸出的結果作爲字符串返回
此外,還有 Printf、 Fprintf、Sprintf 幾個函數來支持定製輸出風格。用法與 fmt 的函數相似。
自定義配置
go-spew 支持一些自定義配置,可以通過 spew.Config 修改。
一些常用配置如下:
-
Indent 修改分隔符
-
MaxDepth 控制遍歷最大深度
-
DisablePointerAddresses 控制是否打印指針類型數據地址
此外還有其他很多配置,大家可以自己測試一下,這裏不再舉例。
小結
go-spew 是一個非常完美的輸出 Go 數據結構的調試工具,並且經過了全面的測試,測試覆蓋率爲 100%。該工具支持各種自定義配置,非常方便,可以有效提升我們日常開發的效率。
References
-
davecgh/go-spew: Implements a deep pretty printer for Go data structures to aid in debugging (github.com)
-
飛雪無情的博客 (flysnow.org)
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/qfukFmJRcBAjn-e2K73VLQ