In Python 2.7, if I encode JSON I get unicode-escaped strings:
>>> import json
>>> s = {"text": "三杯雞"}
>>> print(json.dumps(s))
it gives this output:
{"text": "\u4e09\u676f\u96de"}
But in Go, similar code:
package main
import (
"encoding/json"
"fmt"
)
type Food struct {
Name string `json:"name"`
}
func main() {
food := Food{Name: "三杯雞"}
v, _ := json.Marshal(food)
fmt.Println(string(v))
}
Gives this:
{"name":"三杯雞"}
The Chinese characters are not escaped. I am porting API endpoints from Python to Go - how can I get it to have the same escaped output as Python?
I tried variations using strconv.QuoteToASCII
, but they result in the unicode being double-escaped:
func main() {
s := strconv.QuoteToASCII("三杯雞")
s = strings.Trim(s, "\"")
food := Food{Name: s}
v, _ := json.Marshal(food)
fmt.Println(string(v))
}
Outputs:
{"name":"\\u4e09\\u676f\\u96de"}
One solution is to use the strconv.QuoteToASCII
method inside of a custom JSON marshaler:
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type Food struct {
Name utf8String `json:"name"`
}
type utf8String string
func (s utf8String) MarshalJSON() ([]byte, error) {
return []byte(strconv.QuoteToASCII(string(s))), nil
}
func main() {
food := Food{Name: utf8String("三杯雞")}
v, _ := json.Marshal(food)
fmt.Println(string(v))
}
Output:
{"name":"\u4e09\u676f\u96de"}
This has the drawback that you can't use a plain string
type in the struct definition, but the final output is ASCII-quoted, just like in Python.