2017-08-26 109 views
0

问题golang |解组任意数据

是否有办法以这种方式马歇尔JSON数据,它可以在零件/部分解组?

让我们假设数据的上半部分是一个“代码”,它将指示下半部分做什么......例如根据“代码”将下半部分解组为特定的结构。


有两种结构可作为下半区发送...

type Range Struct { 
    Start int 
    End int 

} 

type User struct { 
    ID int 
    Pass int 
} 

伪码示例

它可能看起来像这样...

message := &Message{ 
    Code: 4, 
    &Range { 
     Start: 1, 
     End: 10, 
    } 
} 

Itt可能看起来像这样...

message := &Message{ 
    Code: 3, 
    &User { 
     ID: 1, 
     Pass: 1234, 
    } 
} 

所以,解组数据我能...

// get code from top half 
m := Message{} 
err = json.UnMarshallTopHalf(byteArray, &m) 
if m.Code == 4 { 
    // ok, the code was four, lets unmarshall into type Range 
    r := Range{} 
    json.UnmarshalBottomHalf(byteArray, &r) 
} 

我已经看过JSON & Go学习如何编组和解组定义的结构时。我能做到这一点,但我不能任意数据,在上面的例子中想出一个办法......

+1

正确的选择可能是使用的接口,见http://gregtrowbridge.com/golang-json-serialization-with-interfaces/- 没有试过这段代码,但是这种方法看起来是正确的。 – Ravi

+0

@Ravi |我相信这是我必须采取的方法。如果你把它写成某种形式的答案,我会接受它。 –

回答

1

可以在json.RawMessage解组下半区第一,像

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Message struct { 
    Code int 
    Payload json.RawMessage // delay parsing until we know the code 
} 
type Range struct { 
    Start int 
    End int 
} 
type User struct { 
    ID int 
    Pass int 
} 

func MyUnmarshall(m []byte) { 
    var message Message 
    var payload interface{} 
    json.Unmarshal(m, &message) // delay parsing until we know the color space 
    switch message.Code { 
    case 3: 
     payload = new(User) 
    case 4: 
     payload = new(Range) 
    } 
    json.Unmarshal(message.Payload, payload) //err check ommited for readability 
    fmt.Printf("\n%v%+v", message.Code, payload) //do something with data 
} 

func main() { 
    json := []byte(`{"Code": 4, "Payload": {"Start": 1, "End": 10}}`) 
    MyUnmarshall(json) 
    json = []byte(`{"Code": 3, "Payload": {"ID": 1, "Pass": 1234}}`) 
    MyUnmarshall(json) 
} 
+0

这正是我正在寻找的 –

1
type Message struct { 
    Code int `json:"cc"` 
    Range *Range `json:"vvv,omitempty"` 
    User *User `json:"fff,omitempty"` 
} 

然后给定的代码== X,使用范围,如果Y,使用用户。

+0

尽管这种方法非常方便,但实际项目的范围远远大于给出的示例。 –