GoZero中实现Java枚举类

Go语言通过常量和自定义类型模拟Java枚举功能。在GoZero中,可使用常量组+iota实现基础枚举,为枚举类型添加String()方法获取字符串表示,并支持复杂结构和方法。在模型层存储枚举值,逻辑层进行状态验证,API层转换状态文本。还可实现枚举验证器、自定义JSON序列化及工具函数,便于全项目统一使用枚举值,确保类型安全。

1. 基础枚举实现

1.1 使用常量组

// common/enums/user_status.go
package enums

type UserStatus int

const (
    UserStatusNormal UserStatus = iota + 1 // 正常
    UserStatusDisabled                    // 禁用
    UserStatusDeleted                     // 删除
)

func (s UserStatus) String() string {
    switch s {
    case UserStatusNormal:
        return "正常"
    case UserStatusDisabled:
        return "禁用"
    case UserStatusDeleted:
        return "删除"
    default:
        return "未知状态"
    }
}

1.2 使用更复杂的枚举结构 

// common/enums/order_type.go
package enums

type OrderType struct {
    Code int
    Name string
}

var (
    OrderTypeNormal = OrderType{1, "普通订单"}
    OrderTypeGroup  = OrderType{2, "团购订单"}
    OrderTypeFlash  = OrderType{3, "秒杀订单"}
)

func (o OrderType) GetCode() int {
    return o.Code
}

func (o OrderType) GetName() string {
    return o.Name
}

2. 带方法的枚举实现 

// common/enums/payment_method.go
package enums

type PaymentMethod int

const (
    PaymentAlipay PaymentMethod = iota + 1
    PaymentWechat
    PaymentBank
)

func (p PaymentMethod) String() string {
    return [...]string{"支付宝", "微信", "银行卡"}[p-1]
}

func (p PaymentMethod) Code() string {
    return [...]string{"ALIPAY", "WECHAT", "BANK"}[p-1]
}

func (p PaymentMethod) IsOnline() bool {
    return p == PaymentAlipay || p == PaymentWechat
}

// 通过code获取枚举
func FromCode(code string) (PaymentMethod, error) {
    switch code {
    case "ALIPAY":
        return PaymentAlipay, nil
    case "WECHAT":
        return PaymentWechat, nil
    case "BANK":
        return PaymentBank, nil
    default:
        return 0, errors.New("未知的支付方式")
    }
}

3. 在 GoZero 中的使用示例 

3.1 在模型中使用 

// model/user.go
package model

import (
    "yourproject/common/enums"
    "time"
)

type User struct {
    Id        int64     `db:"id"`
    Name      string    `db:"name"`
    Status    int       `db:"status"` // 使用枚举值存储
    CreatedAt time.Time `db:"created_at"`
}

// 获取状态文本
func (u *User) GetStatusText() string {
    return enums.UserStatus(u.Status).String()
}

3.2 在逻辑层使用 

// internal/logic/userlogic.go
package logic

import (
    "context"
    "yourproject/common/enums"
    "yourproject/common/errorx"
)

func (l *UserLogic) DisableUser(id int64) error {
    user, err := l.svcCtx.UserModel.FindOne(l.ctx, id)
    if err != nil {
        return errorx.NewDefaultError("用户不存在")
    }
    
    if user.Status == int(enums.UserStatusDisabled) {
        return errorx.NewCodeError(1001, "用户已禁用")
    }
    
    user.Status = int(enums.UserStatusDisabled)
    err = l.svcCtx.UserModel.Update(l.ctx, user)
    if err != nil {
        return errorx.NewSysError("更新用户状态失败")
    }
    
    return nil
}

 3.3 在API层使用

// types/user.go
package types

import "yourproject/common/enums"

type UserInfo struct {
    Id         int64  `json:"id"`
    Name       string `json:"name"`
    Status     int    `json:"status"`
    StatusText string `json:"statusText"` // 前端展示的文本
}

func (u *UserInfo) TransformStatusText() {
    u.StatusText = enums.UserStatus(u.Status).String()
}

4. 枚举验证器 

 可以在请求参数验证中使用枚举:

// types/userreq.go
package types

import (
    "yourproject/common/enums"
    "github.com/zeromicro/go-zero/core/errorx"
)

type UpdateUserStatusReq struct {
    Id     int64 `json:"id"`
    Status int   `json:"status"`
}

func (req *UpdateUserStatusReq) Validate() error {
    switch req.Status {
    case int(enums.UserStatusNormal), 
         int(enums.UserStatusDisabled), 
         int(enums.UserStatusDeleted):
        return nil
    default:
        return errorx.NewCodeError(1002, "无效的用户状态")
    }
}

5. 枚举JSON序列化 

如果需要自定义JSON序列化: 

// common/enums/gender.go
package enums

import (
    "encoding/json"
    "fmt"
)

type Gender int

const (
    GenderUnknown Gender = 0
    GenderMale    Gender = 1
    GenderFemale  Gender = 2
)

func (g Gender) String() string {
    switch g {
    case GenderMale:
        return "男"
    case GenderFemale:
        return "女"
    default:
        return "未知"
    }
}

// 自定义JSON序列化
func (g Gender) MarshalJSON() ([]byte, error) {
    return json.Marshal(map[string]interface{}{
        "code": int(g),
        "name": g.String(),
    })
}

// 自定义JSON反序列化
func (g *Gender) UnmarshalJSON(data []byte) error {
    var code int
    if err := json.Unmarshal(data, &code); err != nil {
        return err
    }
    
    switch code {
    case 0, 1, 2:
        *g = Gender(code)
        return nil
    default:
        return fmt.Errorf("无效的性别代码: %d", code)
    }
}

6. 枚举工具函数 

 可以添加一些工具函数:

// common/enums/enumutil.go
package enums

// 获取所有用户状态
func GetAllUserStatus() []map[string]interface{} {
    return []map[string]interface{}{
        {"code": UserStatusNormal, "name": UserStatusNormal.String()},
        {"code": UserStatusDisabled, "name": UserStatusDisabled.String()},
        {"code": UserStatusDeleted, "name": UserStatusDeleted.String()},
    }
}

// 检查用户状态是否有效
func IsValidUserStatus(status int) bool {
    switch status {
    case int(UserStatusNormal), 
         int(UserStatusDisabled), 
         int(UserStatusDeleted):
        return true
    default:
        return false
    }
}

 7. 在GoZero API中使用枚举

// api/user.go
package main

import (
    "net/http"
    
    "yourproject/common/enums"
    "yourproject/internal/svc"
    "yourproject/internal/types"
    
    "github.com/zeromicro/go-zero/rest/httpx"
)

func getUserStatusHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 返回所有用户状态枚举
        httpx.OkJson(w, enums.GetAllUserStatus())
    }
}

总结

在GoZero中实现类似Java枚举的功能可以通过以下方式:

  1. 使用 iota 创建基础枚举

  2. 为枚举类型添加 String() 方法实现字符串表示

  3. 添加验证方法确保枚举值有效

  4. 实现自定义JSON序列化和反序列化

  5. 在模型、逻辑层和API层中统一使用枚举

  6. 提供工具函数方便枚举操作

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值