The question How to marshal JSON with bigints? is about marshaling big.Int values into strings in JSON. This question asks, how does one marshal and unmarshal big.Int values natively as numbers in JSON?
Passing around large values marshaled in this manner may be incompatible with other implementations of JSON, particularly JavaScript and jq, as RFC 7159 notes:
Note that when such software is used, numbers that are integers and are in the range
[-(2**53)+1, (2**53)-1]are interoperable in the sense that implementations will agree exactly on their numeric values.
Create a custom type BigInt which implements json.Marshaler and json.Unmarshaler like the following:
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
}
Rationale:
big.Int instead of as a subtype of big.Int so that the methods (Add, SetString, etc.) are keptBigInt don't have to use pointersAs with big.Int the zero value is useful and is equal to the number 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With