如果想在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"`
}
总结
-
使用枚举常量 明确定义状态、性别等有限选项
-
软删除实现 通过
is_deleted
字段标记而非物理删除 -
模型钩子 自动设置默认值和更新时间
-
API层转换 将数据库中的数字转换为可读字符串
-
参数验证 确保传入的枚举值有效