如何在JSON中编组和解组big.Int?

时间:2018-12-31 22:21:49

标签: json go biginteger

问题How to marshal JSON with bigints?是关于将big.Int的值编组为JSON字符串。这个问题问,在JSON中,一个元组和一个元组 big.Int如何将本机值作为数字

以这种方式传递的大值可能与JSON的其他实现不兼容,尤其是JavaScript和jq,如RFC 7159所述:

  

请注意,当使用此类软件时,数字为整数和   在[-(2**53)+1, (2**53)-1]范围内,可以在   感觉实现将在数字上完全一致   值。

1 个答案:

答案 0 :(得分:1)

创建自定义类型BigInt,该自定义类型实现json.Marshalerjson.Unmarshaler,如下所示:

import (
    "fmt"
    "math/big"
)

type BigInt struct {
    big.Int
}

func (b BigInt) MarshalJSON() ([]byte, error) {
    return []byte(b.String()), nil
}

func (b *BigInt) UnmarshalJSON(p []byte) error {
    if string(p) == "null" {
        return nil
    }
    var z big.Int
    _, ok := z.SetString(string(p), 10)
    if !ok {
        return fmt.Errorf("not a valid big integer: %s", p)
    }
    b.Int = z
    return nil
}

理论上:

  • 通过嵌入big.Int的结构类型而不是big.Int的子类型来实现,以便保留方法(Add,SetString等)
  • MarshalJSON采用值接收器,因此使用BigInt编组的值不必使用指针
  • UnmarshalJSON采用指针接收器,因为它修改了接收器;但是,使用BigInt的类型仍然不必使用指针
  • UnmarshalJSON适用于临时值,因为在发生错误的情况下SetString方法在其接收方上具有未定义的行为

big.Int一样,零值很有用,它等于数字0。