首頁 > 軟體

go-spew偵錯利器詳解

2022-06-27 10:00:16

對於應用的偵錯,我們經常會使用 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)

到此這篇關於 go-spew偵錯利器的文章就介紹到這了,更多相關 go-spew偵錯利器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com