Создайте пользовательский тип BigInt
, который реализует json.Marshaler
и json.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
, не использовалиpointers - UnmarshalJSON принимает указатель получателя, потому что он изменяет получатель;однако типы, использующие BigInt, по-прежнему не должны использовать указатели
- UnmarshalJSON работает с временным значением, поскольку метод SetString имеет неопределенное поведение на своем получателе в случае ошибок
Asс big.Int
нулевое значение полезно и равно числу 0.