2017-08-26 107 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

儘管這種方法非常方便,但實際項目的範圍遠遠大於給出的示例。 –