Согласно документации для json.Marshal ...
Имя ключа будет использоваться, если это непустая строка, состоящая только из букв Unicode, цифр,и пунктуация ASCII, за исключением кавычек, обратной косой черты и запятой.
Соответствующий код выглядит как isValidTag
.Согласно комментарию, "символы кавычек зарезервированы" для будущего использования в синтаксисе тега.
func isValidTag(s string) bool {
if s == "" {
return false
}
for _, c := range s {
switch {
case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
// Backslash and quote chars are reserved, but
// otherwise any punctuation chars are allowed
// in a tag name.
case !unicode.IsLetter(c) && !unicode.IsDigit(c):
return false
}
}
return true
}
Вы можете обойти это, используя интерфейс вместо struct.
package main
import (
"fmt"
"encoding/json"
"log"
)
func main() {
jsonStr := `{
"valid_json": "I'm Valid",
"invalid'json": "I should be valid, but I'm not"
}`
var res interface{}
err := json.Unmarshal([]byte(jsonStr), &res)
if err != nil {
log.Fatal(err)
}
m := res.(map[string]interface{})
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case float64:
fmt.Println(k, "is float64", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
}
Подробнее см. "Декодирование произвольных данных" в JSON и Go .