在 Go JSON 中转义 unicode 字符,以便输出与 Python 匹配

Her*_*aaf 3 unicode json go

在 Python 2.7 中,如果我对 JSON 进行编码,我会得到 unicode 转义的字符串:

\n\n
>>> import json\n>>> s = {"text": "\xe4\xb8\x89\xe6\x9d\xaf\xe9\x9b\x9e"}\n>>> print(json.dumps(s))\n
Run Code Online (Sandbox Code Playgroud)\n\n

它给出了这个输出:

\n\n
{"text": "\\u4e09\\u676f\\u96de"}\n
Run Code Online (Sandbox Code Playgroud)\n\n

但在 Go 中,类似的代码:

\n\n
package main\n\nimport (\n    "encoding/json"\n    "fmt"\n)\n\ntype Food struct {\n    Name string `json:"name"`\n}\n\nfunc main() {\n    food := Food{Name: "\xe4\xb8\x89\xe6\x9d\xaf\xe9\x9b\x9e"}\n    v, _ := json.Marshal(food)\n    fmt.Println(string(v))\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

给出这个:

\n\n
{"name":"\xe4\xb8\x89\xe6\x9d\xaf\xe9\x9b\x9e"}\n
Run Code Online (Sandbox Code Playgroud)\n\n

中文字符没有转义。我正在将 API 端点从 Python 移植到 Go - 如何才能使其具有与 Python 相同的转义输出?

\n\n

我尝试使用 的变体strconv.QuoteToASCII,但它们导致 unicode 被双重转义:

\n\n
func main() {\n    s := strconv.QuoteToASCII("\xe4\xb8\x89\xe6\x9d\xaf\xe9\x9b\x9e")\n    s = strings.Trim(s, "\\"")\n    food := Food{Name: s}\n    v, _ := json.Marshal(food)\n    fmt.Println(string(v))\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
{"name":"\\\\u4e09\\\\u676f\\\\u96de"}\n
Run Code Online (Sandbox Code Playgroud)\n

Her*_*aaf 5

一种解决方案是使用strconv.QuoteToASCII自定义 JSON 封送拆收器内部的方法:

\n\n
package main\n\nimport (\n    "encoding/json"\n    "fmt"\n    "strconv"\n)\n\ntype Food struct {\n    Name utf8String `json:"name"`\n}\n\ntype utf8String string\n\nfunc (s utf8String) MarshalJSON() ([]byte, error) {\n    return []byte(strconv.QuoteToASCII(string(s))), nil\n}\n\nfunc main() {\n    food := Food{Name: utf8String("\xe4\xb8\x89\xe6\x9d\xaf\xe9\x9b\x9e")}\n    v, _ := json.Marshal(food)\n    fmt.Println(string(v))\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
{"name":"\\u4e09\\u676f\\u96de"}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样做的缺点是您不能string在结构定义中使用普通类型,但最终输出是 ASCII 引用的,就像在 Python 中一样。

\n