无法将字符串解组为Go类型int64的值。

huangapple go评论100阅读模式
英文:

Cannot unmarshal string into Go value of type int64

问题

我有一个结构体:

type tySurvey struct {
    Id   int64    `json:"id,omitempty"`
    Name string   `json:"name,omitempty"`
}

我使用json.Marshal将JSON字节写入HTML页面。jQuery修改对象中的name字段,并使用jQuery的JSON.stringify对对象进行编码,然后将字符串发送到Go处理程序。

id字段被编码为字符串。

发送的数据:{"id":1} 接收到的数据:{"id":"1"}

问题是,json.Unmarshal无法将该JSON解组,因为id不再是整数。

json: cannot unmarshal string into Go value of type int64

有什么好的方法来处理这样的数据?我不想手动转换每个字段。我希望编写简洁、无bug的代码。

引号不是太糟糕。JavaScript与int64不太兼容。

我想学习一种简单的方法来将带有字符串值的JSON解组为int64值。

英文:

I have struct

type tySurvey struct {
	Id     int64            `json:"id,omitempty"`
	Name   string           `json:"name,omitempty"`
}

I do json.Marshal write JSON bytes in HTML page. jQuery modifies name field in object and encodes object using jQueries JSON.stringify and jQuery posts string to Go handler.

id field encoded as string.

Sent: {"id":1} Received: {"id":"1"}

Problem is that json.Unmarshal fails to unmarshal that JSON because id is not integer anymore.

json: cannot unmarshal string into Go value of type int64

What is best way to handle such data? I do not wish to manually convert every field. I wish to write compact, bug free code.

Quotes is not too bad. JavaScript does not work well with int64.

I would like to learn the easy way to unmarshal json with string values in int64 values.

答案1

得分: 129

这是通过在标签中添加,string来处理的,如下所示:

type tySurvey struct {
   Id   int64  `json:"id,string,omitempty"`
   Name string `json:"name,omitempty"`
}

这可以在Marshal文档的中间部分找到。

请注意,当解码空字符串时,不能通过指定omitempty来使用它,因为它只在编码时使用。

英文:

This is handled by adding ,string to your tag as follows:

type tySurvey struct {
   Id   int64  `json:"id,string,omitempty"`
   Name string `json:"name,omitempty"`
}

This can be found about halfway through the documentation for Marshal.

Please note that you cannot decode the empty string by specifying omitempty as it is only used when encoding.

答案2

得分: 23

使用json.Number

type tySurvey struct {
    Id     json.Number      `json:"id,omitempty"`
    Name   string           `json:"name,omitempty"`
}
英文:

use json.Number

type tySurvey struct {
    Id     json.Number      `json:"id,omitempty"`
    Name   string           `json:"name,omitempty"`
}

答案3

得分: 2

你还可以为int或int64创建一个类型别名,并创建一个自定义的json解析器。

示例代码:

参考

// StringInt 为int类型创建一个类型别名
type StringInt int

// UnmarshalJSON 为StringInt创建一个自定义的解析器
// 这样可以在解析之前检查值的类型

func (st *StringInt) UnmarshalJSON(b []byte) error {
    // 将字节转换为接口
    // 这样可以检查值的类型
    // 如果是可以转换为int的字符串,我们将其转换
    // 否则返回错误
    var item interface{}
    if err := json.Unmarshal(b, &item); err != nil {
        return err
    }
    switch v := item.(type) {
    case int:
        *st = StringInt(v)
    case float64:
        *st = StringInt(int(v))
    case string:
        // 在这里将字符串转换为整数
        i, err := strconv.Atoi(v)
        if err != nil {
            // 字符串可能不是整数类型
            // 所以返回错误
            return err
        }
        *st = StringInt(i)
    }
    return nil
}

func main() {
    type Item struct {
        Name   string    `json:"name"`
        ItemId StringInt `json:"item_id"`
    }
    jsonData := []byte(`{"name":"item 1","item_id":"30"}`)
    var item Item
    err := json.Unmarshal(jsonData, &item)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", item)
}
英文:

You could also create a type alias for int or int64 and create a custom json unmarshaler
Sample code:

Reference

// StringInt create a type alias for type int
type StringInt int

// UnmarshalJSON create a custom unmarshal for the StringInt
/// this helps us check the type of our value before unmarshalling it

func (st *StringInt) UnmarshalJSON(b []byte) error {
    //convert the bytes into an interface
	//this will help us check the type of our value
	//if it is a string that can be converted into a int we convert it
	///otherwise we return an error
	var item interface{}
	if err := json.Unmarshal(b, &item); err != nil {
		return err
	}
	switch v := item.(type) {
	case int:
		*st = StringInt(v)
	case float64:
		*st = StringInt(int(v))
	case string:
		///here convert the string into
		///an integer
		i, err := strconv.Atoi(v)
		if err != nil {
			///the string might not be of integer type
			///so return an error
			return err

		}
		*st = StringInt(i)

	}
	return nil
}

func main() {

	type Item struct {
		Name   string    `json:"name"`
		ItemId StringInt `json:"item_id"`
	}
	jsonData := []byte(`{"name":"item 1","item_id":"30"}`)
	var item Item
	err := json.Unmarshal(jsonData, &item)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%+v\n", item)

}



huangapple
  • 本文由 发表于 2014年1月16日 09:27:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/21151765.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定