fmt structure placeholder
There is a native fmt formatting tool in Golang to print structures, which can be implemented through placeholders %v, %+v, and %#v. The differences between these three types are as follows:
type User struct { Name string Age int } func main() { user := User{ Name: "Zhang San", Age: 95, } ("%v\n", user) ("%+v\n", user) ("%#v\n", user) }
The print result is as follows:
{Zhang San 95}
{Name:Zhang San Age:95}
{Name:"Zhang San", Age:95}
The difference:
- The %v placeholder does not print the structure field name, and the fields are separated by spaces;
- The %+v placeholder prints the field name, and the fields are also separated by spaces;
- The %#v placeholder will print the structure type and field name, and the fields are separated by commas.
Print complex structures
When the fields in the structure are of pointer type, what is it printed directly with placeholders?
Based on the previous example, we add a dog to "Zhang San", where the Dog introduced in the User structure is the pointer type, and the code is as follows:
type Dog struct { Name string Age int } type User struct { Name string Age int Dog *Dog } func main() { dog := Dog{ Name: "Benefit", Age: 2, } user := User{ Name: "Zhang San", Age: 95, Dog: &dog, } (user) ("%v\n", user) ("%+v\n", user) ("%#v\n", user) }
Can all the values be printed out at this time?
{Zhang San 95 0xc000004078}
{Name:Zhang San Age:95 Dog:0xc000004078}
{Name:"Zhang San", Age:95, Dog:(*)(0xc000004078)}
At this time, you can see that the Dog field prints not the value inside the Dog structure, but an address value. Obviously, this is not what we need to see in the log. What we need to see is the specific value of the structure, so how can we print this value?
Plan 1
Implement the String() or GoString() method
There is a Stringer interface in the fmt package in Golang, and there is only one String() method in the interface.
// Stringer is implemented by any value that has a String method, // which defines the ``native'' format for that value. // The String method is used to print values passed as an operand // to any format that accepts a string or to an unformatted printer // such as Print. type Stringer interface { String() string }
We can let the User and Dog structures implement the String() method respectively, which is similar to the toString() method in Java. Based on the previous code, we add the following String() method implementation:
func (d *Dog) String() string { return "{\"name" + "\": \"" + + "\"," + "\"" + "age\": \"" + () + "\"}" } func (u *User) String() string { return "{\"name" + "\": \"" + + "\", \"" + "age\": \"" + () + "\", \"dog\": " + () + "}" }
After running, the printed result is as follows:
{Zhang San 95 {"name": "Baocai","age": "2"}}
{Name:Zhang San Age:95 Dog:{"name": "Wangcai","age": "2"}}
{Name:"Zhang San", Age:95, Dog:(*)(0xc000004078)}
It was found that the implementation of String() method is only valid for %v and %+v placeholders. For %#v placeholders, the structure pointer type it prints is still an address value.
In fact, in the fmt package, below the Stringer interface, we can also see another GoStringer interface:
// GoStringer is implemented by any value that has a GoString method, // which defines the Go syntax for that value. // The GoString method is used to print values passed as an operand // to a %#v format. type GoStringer interface { GoString() string }
The GoString method is used to print values passed as an operand to a %#v format. (The GoString method is used to print values passed as an operand to a %#v format)
After finding it, we can implement the GoString() method and use the %#v placeholder to print the value in the structure pointer type.
Add the following code based on the previous code:
func (d *Dog) GoString() string { return "{\"name" + "\": \"" + + "\"," + "\"" + "age\": \"" + () + "\"}" } func (u *User) GoString() string { return "{\"name" + "\": \"" + + "\", \"" + "age\": \"" + () + "\", \"dog\": " + () + "}" }
After running, the printing results are as follows, and you can print them all now:
{Zhang San 95 {"name": "Baocai","age": "2"}}
{Name:Zhang San Age:95 Dog:{"name": "Wangcai","age": "2"}}
{Name:"Zhang San", Age:95, Dog:{"name": "Wangcai","age": "2"}}
At this point, I feel that this solution is a bit troublesome. Are there any other methods that do not need to maintain String() or GoString()?
Plan 2
Convert to json format
func main() { dog := Dog{ Name: "Benefit", Age: 2, } user := User{ Name: "Zhang San", Age: 95, Dog: &dog, } byteUser, _ := (&user) (string(byteUser)) }
The printing results are as follows. If you use the json library, you can print out the specific values of the structure pointer type directly, which is more convenient:
{"Name":"Zhang San","Age":95,"Dog":{"Name":"Wangcai","Age":2}}
This is the end of this article about the detailed explanation of the two methods of Go printing complex structures. For more related content on Go printing complex structures, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!