【发布时间】:2015-04-30 08:19:07
【问题描述】:
我是 Go 新手,一直在尝试弄清楚如何输出原始的内部 JSON "{\"data\":\"Some data"}" 来自“外部”。到目前为止,没有运气......
这是输入数据:
{
"Outer": "{\"data\":\"Some data\"}"
}
我想得到的是以下带有斜杠的字符串:
{\"data\":\"Some data\"}
【问题讨论】:
我是 Go 新手,一直在尝试弄清楚如何输出原始的内部 JSON "{\"data\":\"Some data"}" 来自“外部”。到目前为止,没有运气......
这是输入数据:
{
"Outer": "{\"data\":\"Some data\"}"
}
我想得到的是以下带有斜杠的字符串:
{\"data\":\"Some data\"}
【问题讨论】:
如果你知道密钥(“Outer”),你可以这样做(on the Playground):
package main
import (
"encoding/json"
"fmt"
)
func main() {
//Creating the maps for JSON
m := map[string]json.RawMessage{}
//Parsing/Unmarshalling JSON encoding/json
err := json.Unmarshal([]byte(input), &m)
if err != nil {
panic(err)
}
fmt.Printf("%s", m["Outer"])
}
const input = `
{
"Outer": "{\"data\":\"Some data\"}"
}
`
请注意,您的示例 json 缺少数据后的最终转义。否则你会得到一个错误。
如果您不知道自己的结构,请参阅this reply,了解如何处理任意嵌套数据。
【讨论】:
{\"data\":\"Some data\"} 完全一样的数据作为字符串返回?
json.RawMessage 和fmt.Printf 用于打印消息。
{\"data\":\"Some data\"} 也存储在变量中(包括斜杠)?
这开始只是对previous answer 的评论,但后来增长了。
虽然你可以解组到一个临时的map[string]interface{}(或map[string]json.RawMessage),如果你只想忽略其他“外部”字段,它可以做很多额外的工作,它还需要检查之前的类型成立
(例如,对于像 {"Outer": 42} 这样的错误/意外输入的情况)。
这可能意味着在上一个答案中添加类似这样的内容:
str, ok := m["Outer"].(string)
if !ok { return errors.New("…") }
err := json.Unmarshal([]byte(str), &actual)
更简单的可能是使用像这样的临时包装类型:
var tmp struct{ Outer string }
err := json.Unmarshal(b, &tmp)
if err != nil { … }
var data actualType
err := json.Unmarshal([]byte(tmp.Outer), &data)
您可以在一个单独的函数中执行此操作,该函数返回您想要的类型(或错误,例如func foo(b []byte) (actualType, error))。
或者,您可以将其变体放入包装器类型上的自定义UnmarshalJSON 方法中,以便实现json.Unmarshaler。
如果您希望能够编组回相同的格式,也可以执行相反的操作。
操场上的完整可运行示例:https://play.golang.org/p/IXU2koyJ1A
【讨论】: