慕工程0101907
您可以为“余额”字段使用带有自定义解组算法的自定义类型。现在有两种可能:处理两种类型:package mainimport ( "encoding/json" "fmt" "strconv")type Int inttype account struct { Name string Balance Int}func (i *Int) UnmarshalJSON(b []byte) (err error) { var s string err = json.Unmarshal(b, &s) if err == nil { var n int n, err = strconv.Atoi(s) if err != nil { return } *i = Int(n) return } var n int err = json.Unmarshal(b, &n) if err == nil { *i = Int(n) } return}func main() { for _, in := range [...]string{ `{"Name": "foo", "Balance": 42}`, `{"Name": "foo", "Balance": "111"}`, } { var a account err := json.Unmarshal([]byte(in), &a) if err != nil { fmt.Printf("Error decoding JSON: %v\n", err) } else { fmt.Printf("Decoded OK: %v\n", a) } }}游乐场链接。只处理一个数字类型,并通过一个合理的错误使其他任何事情失败:package mainimport ( "encoding/json" "fmt")type Int inttype account struct { Name string Balance Int}type FormatError struct { Want string Got string Offset int64}func (fe *FormatError) Error() string { return fmt.Sprintf("Invalid data format at %d: want: %s, got: %s", fe.Offset, fe.Want, fe.Got)}func (i *Int) UnmarshalJSON(b []byte) (err error) { var n int err = json.Unmarshal(b, &n) if err == nil { *i = Int(n) return } if ute, ok := err.(*json.UnmarshalTypeError); ok { err = &FormatError{ Want: "number", Got: ute.Value, Offset: ute.Offset, } } return}func main() { for _, in := range [...]string{ `{"Name": "foo", "Balance": 42}`, `{"Name": "foo", "Balance": "111"}`, } { var a account err := json.Unmarshal([]byte(in), &a) if err != nil { fmt.Printf("Error decoding JSON: %#v\n", err) fmt.Printf("Error decoding JSON: %v\n", err) } else { fmt.Printf("Decoded OK: %v\n", a) } }}游乐场链接。还有第三种可能性:为整个account类型编写自定义解组器,但它需要更多涉及的代码,因为您需要使用encoding/json.Decoder类型的方法实际迭代输入 JSON 数据 。看完你的对于请求中任意数量的整数字段,在 Go 中处理传入请求并返回错误消息“余额必须是字符串”的最佳方法是什么?更仔细,我承认有整个类型的定制解析器唯一明智的可能性,除非你是一个OK第三方软件包实现解析器通过JSON模式支持验证(我想我会看看这个第一次作为juju是一个相当已建立的产品)。