We use Golang (Go Language) development process, will often find the cause of the problem by commissioning by the way, to solve the problem, especially when faced with a very difficult problem, we need to know in the course of a piece of code execution in the context of variable data corresponding to the reason for the estimation problem.
For this type of testing, we use a breakpoint debugging is more, there is by printing log output. Print the log, it may start a commonly used is fmt.Println
output, simple, border. If we see some more information about it, such as line number, you can log
package.
package main import ( "fmt" "log" ) func main() { i := 0 s := "哈哈" fmt.Println(i, s) log.Println(i, s) }
Both these ways is more commonly used, the value of the variable can be printed, some additional information, such as source code line number, time and the like.
So if we want to know a struct
field it? Including field name, type, value, and if a field is struct
, how deep to traverse it? This information is very useful when debugging information is, in particular, we call third-party library, can in this way, data structures, watch variables, and these structures corresponding value information, which is of great help to our development and debugging improve our development efficiency.
go-spew
For the above information, has been a tool to help us do these things, it is the go-spew, go-spew can help developers Golang print data structure, and in a more readable way for developers, you can see the data structure information of a variable.
go get -u github.com/davecgh/go-spew/spew
In the above manner, we can download and install this go-spew go language library, and then you can use it in your project. Or the example above, we see the effect.
package main import ( "fmt" "log" "github.com/davecgh/go-spew/spew" ) func main() { i := 0 s := "哈哈" fmt.Println(i, s) log.Println(i, s) spew.Dump(i, s) }
Output:
0 ha 2019/08/25 09:55:07 ha 0 (int) 0 (String) (len =. 6) "ha"
Comparative information is not complete, type, value, as well as for the length of the string, which is useful for debugging us. Now we'll try the other types.
package main import ( "errors" "github.com/davecgh/go-spew/spew" ) type person struct { Name string } func main() { i := 0 s := "哈哈" m := map[int]string{1: "1", 2: "2"} e := errors.New("嘿嘿,错误") p := person{Name: "张三"} spew.Dump(i, s, m, e, p) }
Here we added an extra map
, a error
port, there is a custom struct
, we also look at the output print run
(int) 0 (String) (len =. 6) "ha" (Map [int] String) (len = 2) { (int). 1: (String) (len =. 1) ". 1", (int) 2: (String) (len =. 1) "2" } (* errors.errorString) (0x1162e158) (Hey, error) (main.person) { the Name: (String) (len =. 6) "San" }
map
The structure of the output data, there is more than type, as well as map
the length and inside of each K-V
type, length and value.
errors.New
Function returns an error
interface, but we pass spew
printing, you can see the specific implementation types, as well as the corresponding pointer address and error information.
Our custom person
is the same, it is possible to print out detailed specific data structure containing information type field, a field type, a field value and the like.
This information can help in debugging convenient for us.
Dump, Fdump, Sdump function
In spew
the time dump
series function, is the most commonly used functions, he can meet most of our needs, rather than their own custom output styles.
dump
Function of the output series with aesthetic style, type, a pointer, length and other information.
Dump
Function, is output to the standard os.Stdout
, that is my console standard output.
Fdump
Function, allow us to customize the output io.Writer
, may be os.Stdout
, may be another *File
, as long as the realization of io.Writer
the interface can be.
func Dump(a ...interface{}) { fdump(&Config, os.Stdout, a...) } func Fdump(w io.Writer, a ...interface{}) { fdump(&Config, w, a...) }
In fact, look at the source code above, you will find that Dump
and Fdump(os.Stdout)
are equivalent.
Sdump
Function, as a result of the output string will return, so you can use it flexible, such as to the server via the API.
func Sdump(a ...interface{}) string { var buf bytes.Buffer fdump(&Config, &buf, a...) return buf.String() }
Concrete is achieved, an bytes.Buffer
output of the stored print, and then converted into a string. Here's bytes.Buffer
achieved io.Writer
, it can be used directly.
Printf, Fprintf, Sprintf function
The above Dump
series of functions, although most can meet our needs, but spew
also provides us with a custom output style function, and their fmt
function is very similar usage.
package main import ( "errors" "github.com/davecgh/go-spew/spew" ) func main() { s := "哈哈" e := errors.New("嘿嘿,错误") spew.Printf("%v\n", s) spew.Printf("%+v\n", s) spew.Printf("%#v\n", s) spew.Printf("%#+v\n", s) spew.Dump(s) spew.Printf("%v\n", e) spew.Printf("%+v\n", e) spew.Printf("%#v\n", e) spew.Printf("%#+v\n", e) spew.Dump(e) }
Through the above example, Demo Printf
series of functions and Dump
different series of functions.
In the above example, we use a string s
, a error
type of error to demonstrate. Run to see the output result.
Ha ha (string) ha (string) ha (string) (len = 6) " ha" <*> Hey, error <*> (0x11704170) Hey, error (* errors.errorString) Hey, error (* errors.errorString ) (0x11704170) Hey, wrong (* errors.errorString) (0x11704170) (hey, error)
For strings s
find different formatting characters v
, +v
, #v
the output is almost the same, and for achieving the error
pointer is not the same type of interface. From the above example we can speculate that the role of these format string.
v
Print the value is substantially minimum output +v
will add a pointer address as part of the output #v
is added as part of the output type #+v
output contains a pointer, but also includes the type, as well as values, and Dump
functions almost
The other two Fprintf
, Sprintf
functions, and use Printf
almost Fprintf
can contents into a format io.Writer
, the Sprintf
string is returned formatted for use
Custom Configuration
spew
The default configuration has been enough for us to use, if not met, can be spew
used to achieve our objective of providing custom configuration. For example, spew
the output format is a space indentation way, we can customize, and replaced \t
.
package main import ( "github.com/davecgh/go-spew/spew" ) func main() { spew.Config.Indent = "\t" spew.Dump(spew.Config) }
Run to see the output, you can see the new line indent has been \t
replaced.
(spew.ConfigState) { Indent: (string) (len=1) "\t", MaxDepth: (int) 0, DisableMethods: (bool) false, DisablePointerMethods: (bool) false, DisablePointerAddresses: (bool) false, DisableCapacities: (bool) false, ContinueOnMethod: (bool) false, SortKeys: (bool) false, SpewKeys: (bool) false }
In addition, there are more useful configuration MaxDepth
, the maximum depth of the representatives of the default output of the structure, such as a field structure is also some structures, such nested layers, there are many layers, sometimes we do not need too many layers output , then it can MaxDepth
be defined, its default value is 0, no restrictions, all output levels.
The output can be seen from the above, spew.Config
in fact, it is a spew.ConfigState
, which is a structure.
type ConfigState struct { Indent string MaxDepth int
DisableMethods bool DisablePointerMethods bool DisablePointerAddresses bool DisableCapacities bool ContinueOnMethod bool SortKeys bool SpewKeys bool }
We can see that it provides a lot of configuration