我想在下面的代码中改进getCustomerFromDTO方法,我需要从接口{}创建一个结构,目前我需要将该接口编组为byte []然后将数组解组到我的结构 - 必须有更好的方式。
我的用例是我通过rabbitmq发送结构并发送它们我使用这个通用的DTO包装器,它有关于它们的其他域特定数据。 当我从兔子mq收到DTO时,消息的一层被解组到我的DTO,然后我需要从该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
}
答案 0 :(得分:11)
在解组DTO之前,请将Data
字段设置为您期望的类型。
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{}
中,因此您的代码看起来像这样:
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
}