如何将JSON文档中的字符串值解组为int类型的变量?

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

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

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.

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