gpt4 book ai didi

json - 如何在不解码两次的情况下在 golang 中解析 JSON

转载 作者:IT王子 更新时间:2023-10-29 01:14:44 25 4
gpt4 key购买 nike

我有一个 Web 套接字连接,它在 JSON 对象中发送不同类型的消息,我想将内容解码为一些已知的结构。为此,我认为我应该执行以下操作:

第 1 步)将 JSON 解码为通用映射[字符串]接口(interface){}

第 2 步)找到我要找的 key

第 3 步)尝试将值转换为我的类型之一(失败)

第 3 步备用)json 编码此值并将其解编为我已知的结构

如果我尝试使用 myStruct, ok := value.(myType) 它会失败,但是如果我对 myStruct 使用 json.marshal(value) 然后 json.unmarshal,它就可以正常工作.那是我应该做的吗?去 json-> map[string]interface{} -> json -> myStruct 对我来说似乎是多余的。

示例代码:

https://play.golang.org/p/to_0Id_ja9

package main

import (
"encoding/json"
"fmt"
)

type Ping struct {
Ping string `json:"ping"`
}

type Ack struct {
Messages []Message `json:"messages"`
}

type Message string

func main() {
testJSON := []byte(`{"ack":{"messages":["Hi there","Hi again"]}}`)
var myAck = Ack{}
var myMap map[string]interface{}
err := json.Unmarshal(testJSON, &myMap)
if err != nil {
fmt.Println("error unmarshalling: ", err)
}
for k, v := range myMap {
fmt.Printf("key: %s, value: %s \n", k, v)

switch k {
case "ping":
fmt.Println(k, " is a ping", v)
case "ack":
fmt.Println(k, " is an ack containing a message list")
ackjson, err := json.Marshal(v)
if err != nil {
fmt.Println("marshal error: ", err)
}
err = json.Unmarshal(ackjson, &myAck)
if err != nil {
fmt.Println("unmarshal error", err)
} else {
fmt.Println("New ack object: ", myAck)
}
default:
fmt.Printf("%s is of a type (%T) I don't know how to handle", k, v)
}
}
}

最佳答案

一种解决方案是通过将值解码为 json.RawMessage 来部分解码数据。而不是接口(interface){}

var myMap map[string]json.RawMessage

稍后在仍然需要的切换中,您不需要编码。只是做:

err = json.Unmarshal(v, &myAck)

Playground : https://play.golang.org/p/NHd3uH5e7z

关于json - 如何在不解码两次的情况下在 golang 中解析 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46536234/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com