Golang: JSON: How do I unmarshal array of strings into []int64

前端 未结 2 1201
粉色の甜心
粉色の甜心 2021-02-11 02:27

Golang encoding/json package lets you use ,string struct tag in order to marshal/unmarshal string values (like \"309230\") into int6

2条回答
  •  后悔当初
    2021-02-11 02:37

    For anyone interested, I found a solution using a custom type having MarshalJSON() and UnmarshalJSON() methods defined.

    type Int64StringSlice []int64
    
    func (slice Int64StringSlice) MarshalJSON() ([]byte, error) {
        values := make([]string, len(slice))
        for i, value := range []int64(slice) {
            values[i] = fmt.Sprintf(`"%v"`, value)
        }
    
        return []byte(fmt.Sprintf("[%v]", strings.Join(values, ","))), nil
    }
    
    func (slice *Int64StringSlice) UnmarshalJSON(b []byte) error {
        // Try array of strings first.
        var values []string
        err := json.Unmarshal(b, &values)
        if err != nil {
            // Fall back to array of integers:
            var values []int64
            if err := json.Unmarshal(b, &values); err != nil {
                return err
            }
            *slice = values
            return nil
        }
        *slice = make([]int64, len(values))
        for i, value := range values {
            value, err := strconv.ParseInt(value, 10, 64)
            if err != nil {
                return err
            }
            (*slice)[i] = value
        }
        return nil
    }
    

    The above solution marshals []int64 into JSON string array. Unmarshaling works from both JSON string and integer arrays, ie.:

    {"bars": ["1729382256910270462", "309286902808622", "23"]}
    
    {"bars": [1729382256910270462, 309286902808622, 23]}
    

    See example at https://play.golang.org/p/BOqUBGR3DXm

提交回复
热议问题