将不同服务中相似的枚举类型进行转换。

huangapple go评论79阅读模式
英文:

Converting between similar enums from different services

问题

我正在实现一个通过 gRPC API 公开枚举的服务。
这个服务还调用了另一个定义了相同枚举的 gRPC API。

这两个枚举是在不同的包中定义的(自动生成的代码)。

在 Go 编程语言中,我该如何无缝地在它们之间进行转换?

谢谢!

英文:

I'm implementing a service that exposes an enum through a gRPC api.
This service also calls another gRPC API that defines the same enum.

Both enums are defined in different packages (autogenerated code).

How can I seamlessly convert between them in the Go programming language?

Thanks!

答案1

得分: 5

让我们假设我们有以下枚举类型:

  • Select
  • Choose

类型转换 - Playground

如果底层类型和值相同,那么可以使用类型转换。

type Select int32
type Choose int32

const SelectCat Select = 0
const ChooseCat Choose = 0

func main() {
  fmt.Println(Choose(SelectCat) == ChooseCat)
}

映射类型 - Playground

在所有情况下,您可以使用映射来在两个枚举类型之间进行转换。

type Select int32
type Choose string

const SelectCat Select = 0
const ChooseCat Choose = "cat"

var selectAToChooseOne = map[SelectA]ChooseOne{
  SelectACat: ChooseOneCat,
}

func SelectToChoose(selected Select) (Choose, bool) {
	chosen, ok := selectToChoose[selected]

	return chosen, ok
}

func ChooseToSelect(chosen Choose) (Select, bool) {
	for s, c := range selectToChoose {
		if c == chosen {
			return s, true
		}
	}

	return Select(-1), false
}

func main() {
  chosen, ok := SelectToChoose(SelectCat)
  _ = ok // do something with ok

  fmt.Println(chosen == ChooseCat)
}

在这种情况下,从 Select 类型到 Choose 类型的查找将更快。这是因为 SelectToChoose 直接使用底层映射来查找值。然而,ChooseToSelect 需要遍历每个键/值(Select/Choose)对来找到正确的匹配项。我在这些方法中添加了一个 ok,但这不是必需的。

英文:

Let's presume we have the following enum types

  • Select
  • Choose

Type Conversion - Playground

If the underlying types & values are the same, then you can use type conversions

type Select int32
type Choose int32

const SelectCat Select = 0
const ChooseCat Choose = 0

func main() {
  fmt.Println(Choose(SelectCat) == ChooseCat)
}

Mapping Types - Playground

In all situations, you can use a map to convert between the 2 Enums

type Select int32
type Choose string

const SelectCat Select = 0
const ChooseCat Choose = "cat"

var selectAToChooseOne = map[SelectA]ChooseOne{
  SelectACat: ChooseOneCat,
}

func SelectToChoose(selected Select) (Choose, bool) {
	chosen, ok := selectToChoose[selected]

	return chosen, ok
}

func ChooseToSelect(chosen Choose) (Select, bool) {
	for s, c := range selectToChoose {
		if c == chosen {
			return s, true
		}
	}

	return Select(-1), false
}

func main() {
  chosen, ok := SelectToChoose(SelectCat)
  _ = ok // do something with ok

  fmt.Println(chosen == ChooseCat)
}

In this case lookups going from Select kinds to Choose kinds will be quicker. This is because SelectToChoose directly uses the underlying mapping to lookup values. ChooseToSelect however iterates over each key/value (Select/Choose) pair to find the correct match. I've added an ok to these methods, but that isn't a requirement

huangapple
  • 本文由 发表于 2021年6月26日 02:21:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/68135572.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定