【问题标题】:Am I using renamed types correctly in Golang?我在 Golang 中正确使用重命名的类型吗?
【发布时间】:2019-03-01 23:42:22
【问题描述】:

我必须在 Golang 中处理来自 Swagger 定义的 REST API 的巨大整数。由于 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{}}
}
  1. 这真的是我应该做的事情吗?
  2. 为什么 golang 不能像 int64/uint64/float64 这样的其他内置类型一样对待 big.Int?

【问题讨论】:

  • 需要是指针吗?如果您按原样嵌入 big.Int,那么您可以使用 &BigInt{} 而不是 &BigInt{Int: &big.Int{}}
  • 而且big.Int已经实现了json的Marshaler和Unmarshaler接口,所以你不需要这样做。除了为big.Int 的每个方法或至少您的应用正在使用的方法声明委托方法之外,您对example.Cmp(other.Int) 无能为力。

标签: go


【解决方案1】:

这真的是我应该做的事情吗?

这是一种的方法,但这不是我所说的“重命名”类型;它是一个包含单个字段的结构。你也可以这样做(例如,time.Duration):

type BigInt *big.Int

并对其应用方法。这将允许您在 *big.Int 和您的类型之间无缝转换。

为什么 golang 不能像其他内置类型(如 int64/uint64/float64)一样对待 big.Int?

因为与那些类型不同,big.Int 不是内置类型;你可以知道,因为它是big.Int,也就是说,它是在包中定义的,而不是在语言中。

【讨论】:

  • 我刚试过这个,有一个很大的问题——BigInt 不能使用big.Int 的任何方法!这显然是我采用匿名结构的原因。也许重命名一个类型根本不应该在这里做?
  • 是的,您必须转换回 big.Int 才能使用它的方法。您可能需要从最初的目标/要求开始重新考虑您的设计。
  • @Cirelli94 这不准确。嵌入字段仍然是字段。该结构有一个字段,它是一个嵌入字段。
  • From the spec: “结构是一系列命名元素,称为字段,每个字段都有名称和类型。字段名称可以显式指定(IdentifierList)或隐式指定(EmbeddedField)。 "
  • @Cirelli94 即使它确实像您想象的那样工作,这仍然不会使答案出错,因为解决方案是根本不使用结构 .
猜你喜欢
  • 2020-11-09
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 2022-07-05
  • 1970-01-01
  • 2022-11-25
  • 2020-08-23
  • 2019-10-23
相关资源
最近更新 更多