我想在下面的代码中改进getCustomerFromDTO方法,我需要从interface {}创建一个结构,目前我需要将该接口编组为byte [],然后将数组解组为我的结构-必须有更好的方法。
我的用例是,我通过rabbitmq发送结构,然后使用具有其他特定于域的数据的通用DTO包装器来发送它们。当我从Rabbit 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 }
解组DTO之前,请将Data字段设置为所需的类型。
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) }
如果您无法Data在解组前在DTO上初始化字段,则可以在解组后使用类型断言。encoding/json将interface{}类型值unamrshals 打包到中map[string]interface{},因此您的代码将如下所示:
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 }