RFC 7159说
JavaScript Object Notation(JSON)是用于结构化数据序列化的文本格式.
但Go将JSON视为 []byte
func Marshal(v interface{}) ([]byte, error)
func Unmarshal(data []byte, v interface{}) error
Run Code Online (Sandbox Code Playgroud)
为什么这些函数不能获取并返回string?
我在这里找不到任何解释 https://golang.org/pkg/encoding/json/ https://blog.golang.org/json-and-go
two*_*two 12
围棋也不会去了"字符串文本,字节类型是其他的东西,"像其他一些语言(如Python 3中)做的."在Go中,字符串实际上是一个只读的字节片段." 该string类型具有一些附加的行为,这些行为对于处理UTF-8文本很方便,但它会保存您放入其中的任何字节.标准库中的文本处理内容经常被编写为与[]bytes 一起使用,例如包bytes镜像包strings和regexp处理.
鉴于没有关于文本/二进制在语义上属于一种类型或另一种类型的规则,使用的选择[]byte可能是出于实际原因.由于字符串是只读字节切片,因此几乎所有更改字符串的操作都必须将字节复制到新字符串,而不是修改现有字符串.(字符串切片是一个关键的例外;它只是创建一个新的字符串标头,可以指向旧字符串的字节.)
复制每个操作的字符串内容会导致二次减速,因为字符串长度和副本数都随输入大小增加.除了副本的直接成本之外,为它们分配空间使得垃圾收集更频繁地发生.出于这些原因,几乎所有通过Go中的大量小型操作构建内容的内容都在[]byte内部使用.这包括JSON编组代码.这与Java和C#使用字符串构建器类和现代JavaScript VM有明智的技巧来推迟复制字节直到经过一系列连续操作(为了更多,阅读V8的cons字符串和SpiderMonkey的绳索)有关.
因为strings.Builders是读写的,字符串是只读的,所以将一个转换为另一个也必须复制字节.如果MarshalJSON返回a []byte,则需要制作内容的另一个副本(以及GC上的相关负载).此外,如果您最终要使用此操作进行I/O,则string需要一个字节切片,因此您必须转换回来,创建另一个副本.所以它返回Write()内部构建的; *os.File如果你需要WriteString(),你当然可以调用结果,复制不是问题.
有点超出原始问题的范围,但通常最佳性能选项只是将输出直接流式传输到json.Encoder使用a []byte.您永远不必一次分配整个输出块,并且它可以使您的代码更简单,因为没有临时变量,您可以在一个地方处理编组和I/O错误.
| 归档时间: |
|
| 查看次数: |
418 次 |
| 最近记录: |