可以将map [string] string编组到json会返回错误吗? [英] Can marshalling a map[string]string to json return an error?

查看:111
本文介绍了可以将map [string] string编组到json会返回错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有以下代码:

m := map[string]string{}
//... do stuff to the map
b, err := json.Marshal(m)

在这种情况下,json.Marshal调用是否会返回错误?

Is there any way in this case that the json.Marshal call would return an error?

我想知道,部分原因是出于好奇,另一部分是考虑是否需要担心该错误检查.

I'm wondering partly out of curiosity and partly to consider whether I need to worry about that error check at all.

推荐答案

由于任何有效的string值都是有效的键,而且也是JSON中的有效值(有关详细信息,请参见

Since any valid string value is a valid key and also a valid value in JSON (for details see Which characters are valid/invalid in a JSON key name?), theoretically it won't return any errors.

如果发生内存不足错误,则 json.Marshal() 不会返回,您的应用将以错误代码终止.

If an out of memory error would occur, json.Marshal() would not return, your app would terminate with an error code.

由于Go将string值存储为其UTF-8编码的字节序列,因此存在无效的UTF-8编码的字符串内容的问题.这也不会导致任何错误,因为Go会将无效代码点替换为Unicode替换字符U + FFFD,例如以下示例:

Since Go stores string values as their UTF-8 encoded byte sequences, there is the question of invalid UTF-8 encoded string content. This also won't result in any errors, as Go will substitute invalid code points with the Unicode replacement character U+FFFD, like in this example:

m := map[string]string{"\xff": "a"}
data, err := json.Marshal(m)
fmt.Println(string(data), err)

输出(在游乐场上尝试):

{"\ufffd":"a"} <nil>

此行为记录在json.Marshal():

字符串值编码为强制转换为有效UTF-8的JSON字符串,用Unicode替换符文替换无效字节.

String values encode as JSON strings coerced to valid UTF-8, replacing invalid bytes with the Unicode replacement rune.

封送map[string]string可能永远不会返回错误,但是,除非文档明确指出返回的error始终为nil(json.Marshal()的文档确实如此),否则您应该始终检查返回的错误.没有记录这种行为).这样的罕见示例是 rand.Read() ,该文档记录了"它总是返回len(p)和nil错误"..

It may be that marshaling a map[string]string will never return an error, still, you should always check returned errors unless the doc explicitly states that the returned error is always nil (the doc of json.Marshal() does not document such behavior). Such rare example is rand.Read() which documents that "it always returns len(p) and a nil error".

标准库也有可能出错,因此即使编组map[string]stringjson包的实现可能不会 intend 返回任何错误,可能会导致它仍然返回非nil错误.

And there is also the possibility that the standard library has errors, so even though the implementation of the json package may not intend to return any error when marshaling a map[string]string, a bug may cause it to still return a non-nil error.

另请参阅相关问题:转到: json.Unmarshal何时会返回结构错误?

为完整起见,让我们讨论另一个问题,当将map[string]string传递给它时,该问题可能导致json.Marshal()失败.

For completeness, let's discuss another issue that might cause json.Marshal() to fail when a map[string]string is passed to it.

添加了1.6版轻度并发地将地图检测误用到运行时,您可以在此处了解更多信息:如何从并发映射写入中恢复?

Go 1.6 added a lightweight concurrent misuse of maps detection to the runtime, you can read more about it here: How to recover from concurrent map writes?

这意味着Go运行时可以检测是否在goroutine中读取或修改了地图,并且还同时由另一个goroutine对其进行了修改,而无需同步.

This means that the Go runtime may detect if a map is read or modified in a goroutine, and it is also modified by another goroutine, concurrently, without synchronization.

因此,这里的情况是我们将map[string]string传递给json.Marshal().而要使其被封送,json包显然必须遍历地图的键值.如果我们同时修改地图,将导致失败.

So the scenario here is that we pass a map[string]string to json.Marshal(). And for it to be marshaled, the json package has to iterate over the key-values of the map obviously. If we modify the map concurrently, that will result in a fail.

这里是一个激发它的示例代码(存在循环以增加并发修改的可能性,否则我们将由goroutine调度程序处理):

Here is a sample code that provokes it (the loop is there to increase the likeliness of the concurrent modification, else we would be in the hands of the goroutine scheduler):

m := map[string]string{"\xff": "a"}

go func() {
    for i := 0; i < 10000; i++ {
        m["x"] = "b"
    }
}()

for i := 0; i < 10000; i++ {
    if _, err := json.Marshal(m); err != nil {
        panic(err)
    }
}

还请注意,在这种情况下,json.Marshal()也不会返回(就像发生内存不足错误的情况一样),而是运行时将有意使您的应用程序崩溃.输出将是:

Also note that in this case json.Marshal() will also not return (just like with the case of the out-of-memory error), instead the runtime will crash your app, intentionally. Output will be:

fatal error: concurrent map iteration and map write

这篇关于可以将map [string] string编组到json会返回错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆