当我对REST API进行HTTP调用时,我可能会将JSON值count
作为数字或字符串返回。在任何一种情况下,我都想把它整理成一个整数。我怎么能在Go中处理这个问题?。
答案 0 :(得分:8)
使用"字符串"字段标记选项,指定应将字符串转换为数字。该选项的documentation为:
"字符串"选项表示字段在JSON编码的字符串中存储为JSON。它仅适用于字符串,浮点,整数或布尔类型的字段。在与JavaScript程序通信时,有时会使用这种额外的编码级别:
以下是一个使用示例:
type S struct {
Count int `json:"count,string"`
}
如果JSON值可以是数字或字符串,则解组到接口{}并在解组后转换为int:
Count interface{} `json:"count,string"`
使用此函数将interface {}值转换为int:
func getInt(v interface{}) (int, error) {
switch v := v.(type) {
case float64:
return int(v), nil
case string:
c, err := strconv.Atoi(v)
if err != nil {
return 0, err
}
default:
return 0, fmt.Errorf("conversion to int from %T not supported", v)
}
}
答案 1 :(得分:0)
// Format of your expected request
type request struct {
ACTIVE string `json:"active"`
CATEGORY string `json:"category"`
}
// struct to read JSON input
var myReq request
// Decode the received JSON request to struct
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&myReq)
if err != nil {
log.Println( err)
// Handler for invalid JSON received or if you want to decode the request using another struct with int.
return
}
defer r.Body.Close()
// Convert string to int
numActive, err = strconv.Atoi(myReq.ACTIVE)
if err != nil {
log.Println(err)
// Handler for invalid int received
return
}
// Convert string to int
numCategory, err = strconv.Atoi(myReq.CATEGORY)
if err != nil {
log.Println(err)
// Handler for invalid int received
return
}
答案 2 :(得分:0)
对于值列表,其中值是字符串或结构,我也遇到了同样的问题。我正在使用的解决方案是创建一个具有预期类型的字段的辅助结构,并将值解析为正确的字段。
type Flag struct {
ID string `json:"id"`
Type string `json:"type"`
}
type FlagOrString struct {
Flag *Flag
String *string
}
func (f *FlagOrString) UnmarshalJSON(b []byte) error {
start := []byte("\"")
for idx := range start {
if b[idx] != start[idx] {
return json.Unmarshal(b, &f.Flag)
}
}
return json.Unmarshal(b, &f.String)
}
var MainStruct struct {
Vals []FlagOrString
}
自定义Unmarshaller
简化了代码。我个人更喜欢interface{}
,因为它明确说明了开发人员的期望。