2017-04-10 25 views
1

を構造体へのIは、以下のコードでgetCustomerFromDTO方法を改善したい、インタフェースは、バイトすることを私はインターフェイス{}から構造体を作成する必要があり、現在iはマーシャルに必要[]、次いでアレイアンマーシャル私の構造体には、より良い方法が必要です。Golangインターフェイスを変換{}

私のユースケースは、私がRabbitMQのを経由して構造体を送信し、私はそれらについての追加のドメイン固有のデータを持っている。この一般的なDTOラッパーを使用してそれらを送信することです。 私はウサギのmqからDTOを受け取ると、メッセージの下の1層が私の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 
} 

答えて

7

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フィールドを初期化する能力を持っていない場合は、非整列化した後、型アサーションを使用することができます。パッケージmap[string]interface{}encoding/json unamrshals 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 
} 
+0

DTOのマーシャリング解除は、私が使用したパッケージによって行われ、それがすべてのメッセージを受信するために同じです。私のアプリケーションでは、すでに非整列のDTOを受け取っています – Tomas

+0

そしてこのパッケージを変更する権限はありませんか?サードパーティですか? – mkopriva

+0

私はそれを変更することができますが、一般的な目的のパッケージであるため、私はDTOを非整列化します。データフィールドの構造体の型がわかりません – Tomas

関連する問題