选项用于u而不是Unicode替换



如果我运行这个Go代码:

package main
import (
"encoding/json"
"os"
)
func main() {
json.NewEncoder(os.Stdout).Encode("xa1") // "ufffd"
}

我丢失了数据,因为一旦Unicode替换完成,我就不能再得到返回原始值。与以下Python代码比较:

import json
a = 'xa1'
b = json.dumps(a) # "u00a1"
print(json.loads(b) == a) # True

没有替换,所以没有数据丢失。另外,生成的JSON是仍然有效。Go有一些方法来编码JSON字符串与转义而不是替换?

这个例子是一个假等价。'xa1'在Python中是一个有效的Unicode字符串,它只是一种可能的表示形式,如'u00a1''U000000a1'chr(0xa1)'N{INVERTED EXCLAMATION MARK}''¡'或…

在Python代码中等效为:

>>> print(json.dumps(b'xa1'.decode(errors='replace')))
"ufffd"

在标准输出时也打印强制替换字符的ascii表示形式,与Go中相同。

这是因为"xa1"不是一个有效的Unicode字符串。它包含字节0xa1,这是无效的(本身无效)。无效字节将被U+FFFD替换,这是"替换字符"-在输入无效时使用。

如果要编码Unicode字符U+00A1,则将其写成"u00a1"。如果您想让任意数据通过JSON来回传输,则必须以不同的方式表示它(例如,像base64编码它)。

Python的工作方式不同——在Python中,xa1转义序列是U+00A1。同样,在Go中,xa1是字节0xa1,它本身不是一个有效的Unicode字符串,并且不能被编码为JSON字符串。

最新更新