从 Go int64/uint64 from/to Javascript 字符串序列化反序列化

Serialize deserialize from Go int64/uint64 from/to Javascript string

是否可以修改 json 序列化和反序列化,以便像这样的结构:

type Foo struct {
   A int64
   B uint64
   // and other stuff with int64 and uint64 and there's a lot of struct that are like this
}

x := Foo{A: 1234567890987654, B: 987654321012345678}
byt, err := json.Marshal(x)
fmt.Println(err)
fmt.Println(string(byt))

//                                 9223372036854775808      9223372036854775808
err = json.Unmarshal([]byte(`{"A":"12345678901234567", "B":"98765432101234567"}`), &x)
// ^ must be quoted since javascript can't represent those values properly (2^53)
// ^ json: cannot unmarshal string into Go struct field Foo.A of type int64
fmt.Println(err)
fmt.Printf("%#v\n", x)
// main.Foo{A:1234567890987654, B:0xdb4da5f44d20b4e}

https://play.golang.org/p/dHN-FcJ7p-N

以便它可以接收 json 字符串但解析为 int64/uint64,并且可以将 int64/uint64 反序列化为 json 字符串而无需修改结构或结构标记全部

在 JSON 结构标签中使用 string option。它专为这个用例设计:

The "string" option signals that a field is stored as JSON inside a JSON-encoded string. It applies only to fields of string, floating point, integer, or boolean types. This extra level of encoding is sometimes used when communicating with JavaScript programs

type Foo struct {
    A int64  `json:"A,string"`
    B uint64 `json:"B,string"`
}

func main() {
    x := &Foo{}
    _ = json.Unmarshal([]byte(`{"A":"12345678901234567", "B":"98765432101234567"}`), x)

    fmt.Println(x) // &{12345678901234567 98765432101234567}

    b, _ := json.Marshal(x)

    fmt.Println(string(b)) // {"A":"12345678901234567","B":"98765432101234567"}
}

游乐场:https://play.golang.org/p/IfpcYOlcKMo

如果您不能修改现有的结构标签(但您的示例有 none),那么您必须在自定义 UnmarshalJSON 中重新实现此 string 标签选项和 MarshalJSON 方法。