我必须处理来自Swagger定义的REST API的Golang中的巨大整数。由于Swagger需要一个Validate(strfmt.Registry)
,因此我可以这样定义我的自定义类型:
// BigInt is a big.Int, but includes a Validate() method for swagger
// Once created, it can be used just like a big.Int.
type BigInt struct {
*big.Int
}
由于需要与JSON进行转换,因此我定义了一些JSON Marshaling接口:
// UnmarshalJSON implements encoding/json/RawMessage.UnmarshalJSON
func (b *BigInt) UnmarshalJSON(data []byte) error {
err := json.Unmarshal(data, &b.Int)
if err != nil {
return err
}
return nil
}
// MarshalJSON calls json.Marshal() on the BigInt.Int field.
func (b *BigInt) MarshalJSON() ([]byte, error) {
if b == nil {
return []byte("null"), nil
}
return json.Marshal(b.Int)
}
现在,我意识到我的自定义类型实际上并不完全像big.Int
。为了比较两个BigInts:
example := BigInt{Int: &big.Int{}}
other := BigInt{Int: &big.Int{}}
example.Cmp(other.Int)
我做不到
example.Cmp(other)
这更干净。创建BigInt也是一种糟糕的体验,我必须将其包装成这样的函数:
// NewBigInt creates a BigInt with its Int struct field
func NewBigInt() (i *BigInt) {
return &BigInt{Int: &big.Int{}}
}
int64/uint64/float64
一样对待?答案 0 :(得分:2)
这真的是我应该做的事情吗?
这是一种的实现方式,但这不是我所说的“重命名”类型;这是一个包含单个字段的结构。您也可以这样做(例如,time.Duration
):
type BigInt *big.Int
并对其应用方法。这样一来,您就可以在*big.Int
和您的类型之间进行无缝转换。
为什么golang无法将big.Int像其他内置类型(如int64 / uint64 / float64)一样对待?
由于与那些类型不同,big.Int
不是内置类型;您可以知道,因为它是big.Int
,也就是说,它是在包中定义的,而不是在语言中定义的。