Golang将interface {}转换为struct

Tom*_*mas 7 go

我想在下面的代码中改进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
}
Run Code Online (Sandbox Code Playgroud)

mko*_*iva 16

在解组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)
}
Run Code Online (Sandbox Code Playgroud)

如果您无法Data在解组之前初始化DTO上的字段,则可以在解组后使用类型断言.将encoding/jsonunamrshals interface{}类型值打包为a 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
}
Run Code Online (Sandbox Code Playgroud)