How do I unmarshal a string value from a JSON document into a variable of type int?

那年仲夏 提交于 2019-12-13 11:05:53

问题


My struct:

type User struct {
    FirstName     string `json:"firstname, omitempty" validate:"required"` 
    LastName      string `json:"lastname, omitempty" validate:"required"`
    NumberofDays  int   `json:"numberofdays, string" validate:"min=0,max=100"`
}

Value for NumberofDays is passed as string from the server but I want to check if it is within range and store as int.

Ex: user := &User{"Michael","Msk","3"}

I'm getting 'cannot unmarshal string into Go value of type int'.

I'm not sure how to typecast to int and do the validation


回答1:


Remove the space after the comma in the struct tags, e.g. json:"numberofdays, string" should be json:"numberofdays,string". With the space, the json package ignores the string part, hence the error message you're getting. Without the space, the error goes away and behavior is as expected.

Demo comparing the two here: https://play.golang.org/p/AUImnw_PIS

Documentation of json package struct tags: https://golang.org/pkg/encoding/json/#Marshal




回答2:


You can use a custom type to unmarshal a string to an integer value using whatever set of parsing rules you want this mapping to use:

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
)

type User struct {
    FirstName    string `json:"firstname,omitempty" validate:"required"`
    LastName     string `json:"lastname,omitempty" validate:"required"`
    NumberofDays StrInt `json:"numberofdays" validate:"min=0,max=100"`
}

type StrInt int

func (si *StrInt) UnmarshalJSON(b []byte) error {
    var s string
    err := json.Unmarshal(b, &s)
    if err != nil {
        return err
    }

    n, err := strconv.ParseInt(s, 10, 0)
    if err != nil {
        return err
    }

    *si = StrInt(n)
    return nil
}

const data = `{
    "FirstName": "John",
    "LastName": "Doe",
    "NumberOfDays": "42"
}`

func main() {
    var u User
    err := json.Unmarshal([]byte(data), &u)
    if err != nil {
        panic(err)
    }
    fmt.Println(u)
}

Playground.

The idea is as follows:

  1. Have a custom type which is mostly int but allows defining custom methods on it.
  2. Have that type satisfy the encoding/json.Unmarshaler interface by implementing the UnmarshalJSON() method on a pointer to that type.
  3. In the method, first unmarshal the value as its native type—string—and then parse it as an integer.

This approach might appear to be weird, but if you'll think of it a bit more, there's no single "true" string representation of an integer: there are different bases and different conventions at representing integers even in a particular base.

In your unmarshaling method you implement the policy of the text representation of your integers.




回答3:


The json package defines a custom type json.Number for these cases.



来源:https://stackoverflow.com/questions/47206552/how-do-i-unmarshal-a-string-value-from-a-json-document-into-a-variable-of-type-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!