Marshaling map[string]string to JSON: When Can It Return an Error?
Consider the following code snippet:
m := map[string]string{} //... do stuff to the map b, err := json.Marshal(m)
Normally, marshaling a map[string]string to JSON doesn't return errors. JSON supports strings as both keys and values, and Go encodes string values as UTF-8 byte sequences. Even invalid UTF-8 characters are replaced with the Unicode replacement character.
m := map[string]string{"\xff": "a"} data, err := json.Marshal(m) // Output: {"\ufffd":"a"} <nil>
However, it's important to note that returned errors should always be checked, even if the documentation states that the error is typically nil.
A more obscure potential issue arises when a map[string]string is passed to json.Marshal() concurrently. Since Go 1.6, the runtime may detect concurrent misuse of maps. If a thread modifies a map while another thread iterates over it, the runtime may crash the application with a "fatal error: concurrent map iteration and map write" message.
This situation can be provoked like so:
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) } } // Output: fatal error: concurrent map iteration and map write
Therefore, it's crucial to ensure proper synchronization when modifying and marshalling maps concurrently.
The above is the detailed content of When Does `json.Marshal` Fail When Marshaling a `map[string]string` in Go?. For more information, please follow other related articles on the PHP Chinese website!