Golang转换Struct 至 map[string]interface{}

本文介绍Golang转换Struct 至 map[string]interface{},包括默认方法的缺陷以及如何通过其他方法实现。

常规方法问题

Go通常使用struct存储数据,如存储用户信息,可能定义下面结构体:

type UserInfo struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

要把结构体变量转为map[string]interface{},我们可以使用json序列化方法。

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 )
	}
}

输出结果:

=== RUN   TestStructToInterface1
key:age value:18 type:float64
key:name value:q1mi type:string
--- PASS: TestStructToInterface1 (0.00s)

看起来正常,但却有个问题。Go默认json包序列化数值类型(integer,float等)为float64,并不是int类型。这显然不是我们期望的,下面我们利用第三方包规避该问题。

structs库实现转换

structs官方地址:https://github.com/fatih/structs.
使用之前先安装包: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)
	}
}

输出结果:

=== RUN   TestStructToInterface2
key:Name value:q1mi value type:string
key:Age value:18 value type:int
--- PASS: TestStructToInterface2 (0.00s)
PASS

structs 还有很多其他使用示例,读者可以查看文档,该包目前处于不维护状态。

structs转换嵌套结构

我们定义带嵌套类型机构:

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"`
}

测试转换:

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)
	}
}

输出结果:

=== 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

我们看到嵌套结构被映射为 map[string]interface {}类型。

总结

本文介绍json序列化的问题,并引用第三方包struts实现并解决。另外我们也可以通过反射进行实现。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要引用一个golang map[string]interface{},可以使用以下方法: 1. 通过键名引用 可以使用map[key]语法来引用map中的值,其中key是map中的键名。例如: ``` m := map[string]interface{}{ "name": "John", "age": 25, "address": map[string]string{ "street": "123 Main St", "city": "New York", }, } fmt.Println(m["name"]) // Output: John fmt.Println(m["age"]) // Output: 25 fmt.Println(m["address"]) // Output: map[city:New York street:123 Main St] ``` 2. 使用类型断言引用 当map的值是interface{}类型时,可以使用类型断言(type assertion)来获取具体类型的值。例如: ``` m := map[string]interface{}{ "name": "John", "age": 25, } name, ok := m["name"].(string) if ok { fmt.Println(name) // Output: John } ``` 在上面的代码中,我们首先使用类型断言将map中的值转换string类型,然后检查类型断言是否成功。如果成功,我们就可以使用转换后的值。 3. 使用结构体引用 如果map中的值是一个结构体,我们可以使用结构体来引用它。例如: ``` type Address struct { Street string City string } type Person struct { Name string Age int Address Address } m := map[string]interface{}{ "name": "John", "age": 25, "address": Address{ Street: "123 Main St", City: "New York", }, } person := Person{ Name: m["name"].(string), Age: m["age"].(int), Address: m["address"].(Address), } fmt.Println(person.Name) // Output: John fmt.Println(person.Age) // Output: 25 fmt.Println(person.Address.Street) // Output: 123 Main St fmt.Println(person.Address.City) // Output: New York ``` 在上面的代码中,我们首先定义了一个Person结构体和一个Address结构体,然后将map中的值转换为结构体,并将其赋值给person变量。最后,我们可以通过person变量来引用map中的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值