Tips to share: How to implement enumeration in Go?

煎鱼
中文

Hello everyone, I am fried fish.

In daily business engineering development, we often have the appeal of using enumerated values, the enumeration control is good, and the test value boundary is passed over and over...

Some friends will say, isn’t there a iota for enumeration in Go? What else do you talk about in this article about fried fish?

To be fair, the Go language does not have the enum keyword. Friends who have used Protobuf and others know that the Go language only has "limited enumeration" support. We will also use constants to define it. Enumeration values also need to have a literal mapping.

Example

In some business scenarios, it is impossible to meet our demands. Examples are as follows:

type FishType int

const (
 A FishType = iota
 B
 C
 D
)

func main() {
 fmt.Println(A, B, C, D)
}

The output result is: "0 1 2 3". At this time, I am embarrassed... the enumeration value should have a corresponding value in addition to the key. This is what the meaning of "0 1 2 3" corresponds to, should it output "ABCD"

But the Go language has no direct support, so this is not a complete implementation of enumerated types.

At the same time, suppose we pass in FishType type declaration. There will be no control by default in the Go language, and it will be output normally.

The above implementation of Go enumeration is incomplete under certain circumstances and cannot be an enum (enumeration) in the strict sense.

Use String for enumeration

If we want to support the corresponding output of enumeration values, we can do the following:

type FishType int

const (
 A FishType = iota
 B
 C
 D
)

func (f FishType) String() string {
 return [...]string{"A", "B", "C", "D"}[f]
}

Run the program:

func main() {
 var f FishType = A
 fmt.Println(f)
 switch f {
 case A:
  fmt.Println("脑子进煎鱼了")
 case B:
  fmt.Println("记得点赞")
 default:
  fmt.Println("别别别...")
 }
}

Output result:

A
脑子进煎鱼了

We can use the default convention String String method, which will be called when the default output is performed.

In this way, while obtaining the enumeration value, you can also get the literal meaning of its mapping.

Automatically generate String

However, it is troublesome to write manually each time. In this area, we can use the official cmd/string to quickly implement it.

We install the following commands:

go install golang.org/x/tools/cmd/stringer

go:generate instruction on the required enumeration value:

//go:generate stringer -type=FishType
type FishType int

Execute in the project root directory:

go generate ./...

The fishtype\_string.go file will be generated in the root directory:

.
├── fishtype_string.go
├── go.mod
├── go.sum
└── main.go

fishtype\_string file content:

package main

import "strconv"

const _FishType_name = "ABCD"

var _FishType_index = [...]uint8{0, 1, 2, 3, 4}

func (i FishType) String() string {
 if i < 0 || i >= FishType(len(_FishType_index)-1) {
  return "FishType(" + strconv.FormatInt(int64(i), 10) + ")"
 }
 return _FishType_name[_FishType_index[i]:_FishType_index[i+1]]
}

The generated file is mainly based on the enumeration value and the mapping value to make a mapping, and the judgment is made for the scenario that exceeds the enumeration value:

func main() {
 var f1 FishType = A
 fmt.Println(f1)
 var f2 FishType = E
 fmt.Println(f2)
}

Execute go run . view the results of the program:

$ go run .
A
FishType(4)

Summarize

In today's article, we introduced how to implement standard enumeration values in the Go language. Although it is a bit cumbersome, it is not too difficult as a whole.

There are also small partners who have already put forward the "proposal: spec: add typed enum support" proposal in the community. I believe that there will be a chance to see the day when Go itself supports enum (enumeration).

How do you usually implement enumeration in business code? Welcome everyone to leave a message and exchange:)

Welcome everyone to leave a message and exchange in the comment area:)

If you have any questions, welcome feedback and exchanges in the comment area. The best relationship between . Your is the biggest motivation for the creation of fried fish

The article is continuously updated, and you can read it on search [the brain is fried fish], this article 16188aee170876 GitHub github.com/eddycjy/blog has been included, learn the Go language can see Go learning map and route , welcome to update Star.
阅读 3.2k

煎鱼的清汤锅
今天写代码了吗 :-) 博客地址:[链接]
7.9k 声望
12.2k 粉丝
0 条评论
7.9k 声望
12.2k 粉丝
文章目录
宣传栏