部分JSON解组到Go中的地图中

ANi*_*sus 87 json map go

我的websocket服务器将接收和解组JSON数据.此数据将始终包含在具有键/值对的对象中.密钥字符串将充当值标识符,告诉Go服务器它是什么类型的值.通过知道什么类型的值,我可以继续JSON将值解组为正确的结构类型.

每个json对象可能包含多个键/值对.

示例JSON:

{
    "sendMsg":{"user":"ANisus","msg":"Trying to send a message"},
    "say":"Hello"
}
Run Code Online (Sandbox Code Playgroud)

有没有简单的方法使用"encoding/json"包来做到这一点?

package main

import (
    "encoding/json"
    "fmt"
)

// the struct for the value of a "sendMsg"-command
type sendMsg struct {
    user string
    msg  string
}
// The type for the value of a "say"-command
type say string

func main(){
    data := []byte(`{"sendMsg":{"user":"ANisus","msg":"Trying to send a message"},"say":"Hello"}`)

    // This won't work because json.MapObject([]byte) doesn't exist
    objmap, err := json.MapObject(data)

    // This is what I wish the objmap to contain
    //var objmap = map[string][]byte {
    //  "sendMsg": []byte(`{"user":"ANisus","msg":"Trying to send a message"}`),
    //  "say": []byte(`"hello"`),
    //}
    fmt.Printf("%v", objmap)
}
Run Code Online (Sandbox Code Playgroud)

感谢您的任何建议/帮助!

Ste*_*erg 176

这可以通过Unmarshalling成为一个map[string]*json.RawMessage.

var objmap map[string]*json.RawMessage
err := json.Unmarshal(data, &objmap)
Run Code Online (Sandbox Code Playgroud)

要进一步解析sendMsg,您可以执行以下操作:

var s sendMsg
err = json.Unmarshal(*objmap["sendMsg"], &s)
Run Code Online (Sandbox Code Playgroud)

因为say,你可以做同样的事情并解组成一个字符串:

var str string
err = json.Unmarshal(*objmap["say"], &str)
Run Code Online (Sandbox Code Playgroud)

  • 完善!我错过了你如何使用`RawMessage`.正是我需要的.关于`say`,我实际上仍然希望它为`json.RawMessage`,因为字符串仍未解码(包装```和转义`\n`-字符等),所以我也会解组它. (5认同)
  • 类型应该是map [string]*json.RawMessage,因为unmarshal/Marshal方法没有在json.RawMessage上实现. (3认同)
  • 更新到*json.RawMessage后,您现在需要在对json.Unmarshal的调用中取消引用它们. (3认同)

Tab*_*mos 6

这是一个优雅的方式来做类似的事情。但是为什么要部分 JSON 解组呢?那没有意义。

  1. 为聊天创建您的结构。
  2. 将 json 解码为 Struct。
  3. 现在您可以轻松访问 Struct/Object 中的所有内容。

看看下面的工作代码。复制并粘贴它。

import (
   "bytes"
   "encoding/json" // Encoding and Decoding Package
   "fmt"
 )

var messeging = `{
"say":"Hello",
"sendMsg":{
    "user":"ANisus",
    "msg":"Trying to send a message"
   }
}`

type SendMsg struct {
   User string `json:"user"`
   Msg  string `json:"msg"`
}

 type Chat struct {
   Say     string   `json:"say"`
   SendMsg *SendMsg `json:"sendMsg"`
}

func main() {
  /** Clean way to solve Json Decoding in Go */
  /** Excellent solution */

   var chat Chat
   r := bytes.NewReader([]byte(messeging))
   chatErr := json.NewDecoder(r).Decode(&chat)
   errHandler(chatErr)
   fmt.Println(chat.Say)
   fmt.Println(chat.SendMsg.User)
   fmt.Println(chat.SendMsg.Msg)

}

 func errHandler(err error) {
   if err != nil {
     fmt.Println(err)
     return
   }
 }
Run Code Online (Sandbox Code Playgroud)

去游乐场

  • 如果 json 内容不稳定,部分解组也很有用 (4认同)
  • 当您使用数百个嵌套字段的结构作为临时对象时,部分解组是必要的。例如,从服务器获取 json,更新单个字段并将其发布回服务器。 (2认同)