Golang将接口{}转换为struct [英] Golang convert interface{} to struct
问题描述
我想在下面的代码中改进getCustomerFromDTO方法,我需要从接口{}创建一个结构,目前我需要将该接口编组为byte [],然后将数组解组为我的结构-必须存在更好的方法.
I want to improve the getCustomerFromDTO method in the code below, I need to create a struct from an interface{} and currently i need to marshall that interface to byte[] and then unmarshal the array to my struct - there must be a better way.
我的用例是我通过Rabbitmq发送结构,并使用常规DTO包装器发送结构,该包装具有有关它们的其他特定于域的数据.当我从Rabbit MQ接收DTO时,消息下方的一层将被封送给我的DTO,然后我需要从该DTO中获取我的结构.
My use case is that I send structs via rabbitmq and to send them I use this general DTO wrapper that has additional domain specific data about them. When I receive the DTO from rabbit mq one layer below the message is unmarshaled to my DTO and then i need to get my struct from that DTO.
type Customer struct {
Name string `json:"name"`
}
type UniversalDTO struct {
Data interface{} `json:"data"`
// more fields with important meta-data about the message...
}
func main() {
// create a customer, add it to DTO object and marshal it
customer := Customer{Name: "Ben"}
dtoToSend := UniversalDTO{customer}
byteData, _ := json.Marshal(dtoToSend)
// unmarshal it (usually after receiving bytes from somewhere)
receivedDTO := UniversalDTO{}
json.Unmarshal(byteData, &receivedDTO)
//Attempt to unmarshall our customer
receivedCustomer := getCustomerFromDTO(receivedDTO.Data)
fmt.Println(receivedCustomer)
}
func getCustomerFromDTO(data interface{}) Customer {
customer := Customer{}
bodyBytes, _ := json.Marshal(data)
json.Unmarshal(bodyBytes, &customer)
return customer
}
推荐答案
在解组DTO之前,请将 Data
字段设置为所需的类型.
Before unmarshaling the DTO, set the Data
field to the type you expect.
type Customer struct {
Name string `json:"name"`
}
type UniversalDTO struct {
Data interface{} `json:"data"`
// more fields with important meta-data about the message...
}
func main() {
// create a customer, add it to DTO object and marshal it
customer := Customer{Name: "Ben"}
dtoToSend := UniversalDTO{customer}
byteData, _ := json.Marshal(dtoToSend)
// unmarshal it (usually after receiving bytes from somewhere)
receivedCustomer := &Customer{}
receivedDTO := UniversalDTO{Data: receivedCustomer}
json.Unmarshal(byteData, &receivedDTO)
//done
fmt.Println(receivedCustomer)
}
如果在解组前无法在DTO上初始化 Data
字段,则可以在解组后使用类型断言.将 encoding/json
打包将 interface {}
类型的值解散到 map [string] interface {}
中,因此您的代码如下所示:
If you don't have the ability to initialize the Data
field on the DTO before it's unmarshaled, you can use type assertion after the unmarshaling. Package encoding/json
unamrshals interface{}
type values into a map[string]interface{}
, so your code would look something like this:
type Customer struct {
Name string `json:"name"`
}
type UniversalDTO struct {
Data interface{} `json:"data"`
// more fields with important meta-data about the message...
}
func main() {
// create a customer, add it to DTO object and marshal it
customer := Customer{Name: "Ben"}
dtoToSend := UniversalDTO{customer}
byteData, _ := json.Marshal(dtoToSend)
// unmarshal it (usually after receiving bytes from somewhere)
receivedDTO := UniversalDTO{}
json.Unmarshal(byteData, &receivedDTO)
//Attempt to unmarshall our customer
receivedCustomer := getCustomerFromDTO(receivedDTO.Data)
fmt.Println(receivedCustomer)
}
func getCustomerFromDTO(data interface{}) Customer {
m := data.(map[string]interface{})
customer := Customer{}
if name, ok := m["name"].(string); ok {
customer.Name = name
}
return customer
}
这篇关于Golang将接口{}转换为struct的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!