Go map(string)interface to struct
This article introduces how Golang converts Struct to map[string]interface{}, including the defects of the default method and how to achieve it through other methods.
general method problem
Go usually uses struct to store data, such as storing user information, and may define the following structure:
type UserInfo struct {
Name string `json:"name"`
Age int `json:"age"`
}
To convert the structure variable into map[string]interface{}, we can use the json serialization method.
func TestStructToInterface1(t *testing.T) {
u1 := UserInfo{Name: "q1mi", Age: 18}
b, _ := json.Marshal(&u1)
var m map[string]interface{}
_ = json.Unmarshal(b, &m)
for k, v := range m{
fmt.Printf("key:%v value:%v type:%T\n", k, v, v )
}
}
output result
=== RUN TestStructToInterface1
key:age value:18 type:float64
key:name value:q1mi type:string
--- PASS: TestStructToInterface1 (0.00s)
It looks normal, but there is a problem. Go’s default json package serialization value type (integer, float, etc.) is float64, not int type. This is obviously not what we expected, so let’s use a third-party package to avoid this problem.
The structs library implements the conversion
Official address of structs: https://github.com/fatih/structs.
Install the package before using: go get github.com/fatih/structs
func TestStructToInterface2(t *testing.T) {
u1 := UserInfo{Name: "q1mi", Age: 18}
m3 := structs.Map(&u1)
for k, v := range m3 {
fmt.Printf("key:%v value:%v value type:%T\n", k, v, v)
}
}
output result
=== RUN TestStructToInterface2
key:Name value:q1mi value type:string
key:Age value:18 value type:int
--- PASS: TestStructToInterface2 (0.00s)
PASS
There are many other usage examples of structs, readers can check the documentation, the package is currently unmaintained.
structs converts nested structures
We define bodies with nested types:
type UserInfo struct {
Name string `json:"name" structs:"name"`
Age int `json:"age" structs:"age"`
Profile `json:"profile" structs:"profile"`
}
// Profile
type Profile struct {
Hobby string `json:"hobby" structs:"hobby"`
}
test conversion
func TestStructToInterface3(t *testing.T) {
u1 := UserInfo{Name: "q1mi", Age: 18, Profile: Profile{"Two Color Ball"}}
m3 := structs.Map(&u1)
for k, v := range m3 {
fmt.Printf("key:%v value:%v value type:%T\n", k, v, v)
}
}
output result
=== RUN TestStructToInterface3
key:name value:q1mi value type:string
key:age value:18 value type:int
key:profile value:map[hobby:Two Color Ball] value type:map[string]interface {}
--- PASS: TestStructToInterface3 (0.00s)
PASS
We see that nested structures are mapped as map[string]interface{} types.
Summarize
This article introduces the problem of json serialization, and references the third-party package struts to implement and solve it. In addition, we can also implement it through reflection.