GO实现一个文件中实现多个不同类型的枚举

如果想在GO文件中实现一个文件包含多个不同类型的枚举可以通过以下方式实现

以用户信息中的用户状态、软删除标志和性别为例

1. 数据库模型设计

数据库模型定义

type User struct {
    Id         int64     `db:"id"`
    Username   string    `db:"username"`
    Password   string    `db:"password"`
    Status     int       `db:"status"`      // 用户状态
    Gender     int       `db:"gender"`      // 性别
    IsDeleted  int       `db:"is_deleted"`  // 是否删除(0-未删除 1-已删除)
    CreateTime time.Time `db:"create_time"`
    UpdateTime time.Time `db:"update_time"`
}

2. 使用枚举类型

2.1 定义枚举常量

package enum

// 用户状态枚举
type UserStatus int

const (
    UserStatusNormal  UserStatus = 1 // 正常
    UserStatusLocked  UserStatus = 2 // 锁定
    UserStatusDisable UserStatus = 3 // 禁用
)

// 性别枚举
type Gender int

const (
    GenderUnknown Gender = 0 // 未知
    GenderMale    Gender = 1 // 男
    GenderFemale  Gender = 2 // 女
)

// 删除状态枚举
type DeleteStatus int

const (
    NotDeleted DeleteStatus = 0 // 未删除
    IsDeleted  DeleteStatus = 1 // 已删除
)

2.2 为枚举添加方法(可选)

// 用户状态转字符串
func (s UserStatus) String() string {
    switch s {
    case UserStatusNormal:
        return "正常"
    case UserStatusLocked:
        return "锁定"
    case UserStatusDisable:
        return "禁用"
    default:
        return "未知状态"
    }
}

// 性别转字符串
func (g Gender) String() string {
    switch g {
    case GenderMale:
        return "男"
    case GenderFemale:
        return "女"
    default:
        return "未知"
    }
}

3. 在业务逻辑中使用

3.1 查询时过滤已删除用户

func (m *UserModel) FindNotDeletedUsers(ctx context.Context) ([]*User, error) {
    var users []*User
    query := "SELECT * FROM user WHERE is_deleted = ?"
    err := m.conn.QueryRowsCtx(ctx, &users, query, enum.NotDeleted)
    return users, err
}

3.2 更新用户状态 

func (l *UserLogic) LockUser(req *types.LockUserReq) error {
    _, err := l.svcCtx.UserModel.UpdateStatus(l.ctx, req.UserId, enum.UserStatusLocked)
    return err
}

4. 在API层转换枚举 

func (l *UserLogic) GetUserInfo(req *types.GetUserInfoReq) (*types.UserInfoResp, error) {
    user, err := l.svcCtx.UserModel.FindOne(l.ctx, req.UserId)
    if err != nil {
        return nil, err
    }
    
    return &types.UserInfoResp{
        Id:       user.Id,
        Username: user.Username,
        Gender:   enum.Gender(user.Gender).String(), // 转换为可读字符串
        Status:   enum.UserStatus(user.Status).String(),
    }, nil
}

5. 软删除实现

5.1 使用模型钩子

func (u *User) BeforeInsert() error {
    u.IsDeleted = int(enum.NotDeleted)
    u.CreateTime = time.Now()
    u.UpdateTime = time.Now()
    return nil
}

// 软删除方法
func (m *UserModel) SoftDelete(ctx context.Context, id int64) error {
    query := "UPDATE user SET is_deleted = ?, update_time = ? WHERE id = ?"
    _, err := m.conn.ExecCtx(ctx, query, enum.IsDeleted, time.Now(), id)
    return err
}

5.2 查询时自动过滤已删除

可以创建一个基础查询构建器:

func (m *UserModel) buildNotDeletedQuery(query string) string {
    return query + " AND is_deleted = 0"
}

// 使用
query := m.buildNotDeletedQuery("SELECT * FROM user WHERE status = ?")

6. 验证枚举值

在API层验证请求参数中的枚举值:

func (l *UserLogic) UpdateGender(req *types.UpdateGenderReq) error {
    // 验证性别枚举值是否有效
    if req.Gender != int(enum.GenderMale) && req.Gender != int(enum.GenderFemale) {
        return errors.New("无效的性别参数")
    }
    
    _, err := l.svcCtx.UserModel.UpdateGender(l.ctx, req.UserId, req.Gender)
    return err
}

7. 使用自定义类型(推荐)

更优雅的方式是使用自定义类型:

type UserStatus int

func (s *UserStatus) UnmarshalJSON(data []byte) error {
    // 解析并验证状态值
    // ...
}

// 在API请求结构体中使用
type UpdateStatusReq struct {
    UserId int64      `json:"userId"`
    Status UserStatus `json:"status"`
}

总结

  1. 使用枚举常量 明确定义状态、性别等有限选项

  2. 软删除实现 通过 is_deleted 字段标记而非物理删除

  3. 模型钩子 自动设置默认值和更新时间

  4. API层转换 将数据库中的数字转换为可读字符串

  5. 参数验证 确保传入的枚举值有效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值