一.前言
2023/11/10 第一次更新 | 将key的*int修改为string,增强枚举通用性 |
用惯了springboot和Jakarta.才发现springboot和Jakarta的语言是多么精妙! 一些场景我们需要使用枚举: 如建立字典值映射,仅通过代码实现方便快捷; 维护自定义响应码; 维护下拉菜单选项 等.
需要注意的是go建立结构体应尽量避免使用基本数值类型,应当使用`基本数值类型指针`. 因为基本数值类型默认数值可能会与状态值冲突.前端传值无法判nil. 当然也可借助gin等三方框架的校验规则,亦或设置负值默认值.这里给出的是弱依赖,仅用go就能解决的方式....
二. 枚举基本要素描述
在java中我们发现枚举对象操作很方便.
-
- 具备基本包装类型
-
- 可以通过自定义方式快速使用 getKeyByVal
-
- 可以通过自定义方式快速使用 getValByKey
-
- 可以通过自定义方式快速使用 getEnumsList 获取枚举列表.
上述也是我们常用的方式. 那么我们将上述功能还原. 并且
由于go中 1.基本类型和状态值冲突问题 2. 性能考虑 使用指针类型
当然java有些功能太臃肿.比如对象.属性即可;
私有化属性. 通过对象.获取属性的方法()是个伪命题! 这边会优化掉.
三. 枚举设计源码
3.1 EnumCommon-通用能力
在此之前,需要对小白提醒下. go没有文件(类)的概念. go是基于文件夹(包) 来规划代码的.
enum_common.go
package enums
import (
"fmt"
"strings"
)
type EnumCommon struct {
Key string `json:"key"`
Value string `json:"value"`
}
var (
UNDISPOSED = createEnum("0", "未处理")
PROCESSED = createEnum("1", "已处理")
)
func createEnum(key string, value string) *EnumCommon {
return &EnumCommon{
Key: key,
Value: value,
}
}
// IntPtr 是一个辅助函数,用于创建 int 类型的指针
func IntPtr(i int) *int {
return &i
}
// GetEnumCommon 获取当前枚举
func (e *EnumCommon) GetEnumCommon() *EnumCommon {
return &EnumCommon{
Key: e.Key,
Value: e.Value,
}
}
// 获取枚举列表
func GetEnumsList(arr []*EnumCommon) []EnumCommon {
var temp []EnumCommon
for i := 0; i < len(arr); i++ {
temp = append(temp, EnumCommon{
Key: arr[i].Key,
Value: arr[i].Value,
})
}
return temp
}
// GetValByKey 根据key获取val
func GetValByKey(key string, arr []*EnumCommon) string {
for i := 0; i < len(arr); i++ {
if key == arr[i].Key {
return arr[i].Value
}
}
panic(fmt.Sprintf("未找到对应的枚举值."))
}
// GetKeyByVal 根据val获取key
func GetKeyByVal(value string, arr []*EnumCommon) string {
for i := 0; i < len(arr); i++ {
if value == arr[i].Value {
return arr[i].Key
}
}
panic(fmt.Sprintf("未找对应的枚举key."))
}
// 单列枚举判断
func IsContainsElement(name string, arr []string) bool {
if strings.TrimSpace(name) == "" {
return false
}
for _, val := range arr {
if val == name {
return true
}
}
return false
}
业务枚举
package enums
var (
// 发布状态
STATUS_STOP = createEnum("0", "草稿")
STATUS_WAIT = createEnum("1", "审核")
STATUS_ALLOW = createEnum("2", "发布")
// 消息类型
TYPE_JOURNALISM = createEnum("0", "新闻")
TYPE_NOTICE = createEnum("1", "公告")
TYPE_CASE = createEnum("2", "案例")
// 消息格式
STYLE_TEXT = createEnum("0", "text")
STYLE_HTML = createEnum("1", "html")
STYLE_MARKDOWN = createEnum("2", "markdown")
)
// 发布状态枚举遍历能力
var statusArray = []*EnumCommon{
STATUS_STOP, STATUS_WAIT, STATUS_ALLOW}
var typeArray = []*EnumCommon{
TYPE_JOURNALISM, TYPE_NOTICE, TYPE_CASE}
var styleArray = []*EnumCommon{
STYLE_TEXT, STYLE_HTML, STYLE_MARKDOWN}
// GetEnumNewsStatus 获取枚举对象
func GetEnumNewsStatus() []EnumCommon {
return GetEnumsList(statusArray)
}
func GetEnumNewsType() []EnumCommon {
return GetEnumsList(typeArray)
}
func GetEnumNewsStyle() []EnumCommon {
return GetEnumsList(styleArray)
}
// GetValByNewsStatusKey 获取枚举value by key
func GetValByNewsStatusKey(k string) string {
return GetValByKey(k, statusArray)
}
func GetValByNewsTypeKey(k string) string {
return GetValByKey(k, typeArray)
}
func GetValByNewsStyleKey(k string) string {
return GetValByKey(k, styleArray)
}
// GetKeyByNewsStatusVal 获取枚举key by value
func GetKeyByNewsStatusVal(val string) string {
return GetKeyByVal(val, statusArray)
}
func GetKeyByNewsTypeVal(val string) string {
return GetKeyByVal(val, typeArray)
}
func GetKeyByNewsStyleVal(val string) string {
return GetKeyByVal(val, styleArray)
}
3.3 特殊需求定制化业务枚举
比如自定义错误码枚举,通用能力用不了多少.
demo如下
package enums
type MyError struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{
} `json:"data"`
}
var (
LOGIN_UNKNOWN = newError(202, "用户不存在")
LOGIN_ERROR = newError(203, "账号或密码错误")
VALID_ERROR = newError(300, "参数错误")
OPTIONS_ERROR = newError(400, "操作失败")
UNAUTHORIZED = newError(401, "您还未登录")
NOT_FOUND = newError(404, "资源不存在")
SYSTEM_ERROR = newError(500, "系统发生异常")
)
func newError(code int, msg string) *MyError {
return &MyError{
Msg: msg,
Code: code,
}
}
func (e *MyError) Error() string {
return e.Msg
}
func (e *MyError) GetError(data interface{
}) *MyError {
return &MyError{
Msg: e.Msg,
Code: e.Code,
Data: data,
}
}
3.4 特殊单列枚举
var resArray = []string{
"soft", "pic", "video", "audio", "media"}
// 单列枚举判断
func IsContainsElement(name string, array []string) bool {
if name == "" {
return false
}
for _, val := range array {
if val == name {
return true
}
}
return false
}
文章评论