Golang - 通过接口传递2步的Unmarshal /重建对象

Emi*_*m23 1 interface object go

我正在和json和golang一起工作.我已经创建了一个TCP服务器,在解组所包含的数据之前,我需要解组消息以了解所要求的服务类型.这有点难以解释所以这是我的代码:

package main

import (
    "fmt"
    "encoding/json"
)

type Container struct {
    Type string
    Object interface{}
}

type Selling struct {
    Surname string
    Firstname string
    //......
    Price int
}

type Buying struct {
    ID int
    Surname string
    Firstname string
    //..........
}

/*
type Editing struct {
    ID int
    ...............
}
Informations, etc etc
*/

func main() {

    tmp_message_json1 := Selling{Surname: "X", Firstname: "Mister", Price: 10}
    //tmp_message_json1 := Buying{ID: 1, Surname: "X", Firstname: "Mister"}
    tmp_container_json1 := Container{Type: "Selling", Object: tmp_message_json1}
    json_tmp, _ := json.Marshal(tmp_container_json1)

/*...........
We init tcp etc etc and then a message comes up !
...........*/

    c := Container{}
    json.Unmarshal(json_tmp, &c)
    //I unmarshal a first time to know the type of service asked

    //  first question: Does Unmarshal need to be used only one time?
    // does I need to pass c.Object as a string to unmarshal it in the called functions?
    if c.Type == "Buying" {
        takeInterfaceBuying(c.Object)
    } else if c.Type == "client" {
        takeInterfaceSelling(c.Object)
    } else {
        fmt.Println("bad entry")
    }
}

func takeInterfaceBuying(Object interface{}) {

    bu := Object

    fmt.Println(bu.Firstname, bu.Surname, "wants to buy the following product:", bu.ID)
}

func takeInterfaceSelling(Object interface{}) {

    se := Object

    fmt.Println(se.Firstname, se.Surname, "wants to sell something for:", se.Price)
}
Run Code Online (Sandbox Code Playgroud)

我需要处理像它一样出现的消息,但我不知道它是否可能?有可能吗?

谢谢你的帮助!

小智 6

为此目的有json.RawMessage.

package main

import (
    "encoding/json"
    "fmt"
)

type Container struct {
    Type   string
    Object json.RawMessage
}

type Selling struct {
    Surname   string
    Firstname string
    Price     int
}

type Buying struct {
    ID        int
    Surname   string
    Firstname string
}

func main() {
    rawJson1 := []byte(`{"Type":"Selling","Object":{"Surname":"X","Firstname":"Mister","Price":10}}`)
    rawJson2 := []byte(`{"Type":"Buying","Object":{"ID":1,"Surname":"X","Firstname":"Mister"}}`)

    processMessage(rawJson1)
    processMessage(rawJson2)
}

func processMessage(data []byte) {
    var c Container
    json.Unmarshal(data, &c)

    switch {
    case c.Type == "Buying":
        processBuying(c)
    case c.Type == "Selling":
        processSelling(c)
    default:
        fmt.Println("bad entry")
    }
}

func processBuying(c Container) {
    var bu Buying
    json.Unmarshal(c.Object, &bu)
    fmt.Println(bu.Firstname, bu.Surname, "wants to buy the following product:", bu.ID)
}

func processSelling(c Container) {
    var se Selling
    json.Unmarshal(c.Object, &se)
    fmt.Println(se.Firstname, se.Surname, "wants to sell something for:", se.Price)
}
Run Code Online (Sandbox Code Playgroud)