我想像这样定义自定义sql类型enum
:
package db
import (
"database/sql/driver"
"github.com/spf13/cast"
)
type Enum int64
func (e Enum) Value() (driver.Value, error) {
return int64(e), nil
}
func (e *Enum) Scan(v any) error {
*e = Enum(cast.ToInt64(v))
return nil
}
我想使用以下内容:
package db_test
import (
"db"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"testing"
)
type StatusEnum = db.Enum
const (
StatusEnumEnable StatusEnum = iota
StatusEnumDisable
)
// this is error because this type alias can not define new method
//func (e *StatusEnum) String() string{
// if v,ok := StatusEnumMap[*e];ok{
// return v
// }
// return "unknown"
//}
var StatusEnumMap = map[StatusEnum]string{
StatusEnumEnable: "Enable",
StatusEnumDisable: "Disable",
}
type module struct {
Status StatusEnum
}
func TestEnum(t *testing.T) {
db, _ := gorm.Open(sqlite.Open(":memory:"))
db.AutoMigrate(&module{})
db.Model(&module{}).Create(&module{Status: StatusEnumDisable})
var out *module
// SELECT * FROM `modules` WHERE status=1 ORDER BY `modules`.`status` LIMIT 1
db.Debug().Model(&module{}).Where("status=?", StatusEnumDisable).First(&out)
t.Log(out)
t.Log(StatusEnumMap[out.Status])
//t.Log(out.Status.String())
}
现在,当我需要字符串格式时,我会像这样使用StatusEnumMap[EnumValue]
。我认为value.String()
更优雅和简单。fmt
也可以打印字符串而不是数字。
如何更好地实现此功能?谢谢你的建议。
1条答案
按热度按时间gwbalxhn1#
如果底层类型是
int64
,似乎不需要实现Valuer
和Scanner
接口。如果是这样,则不需要Enum
类型。下面的示例在没有Enum
的情况下工作:注意:我稍微修改了一下你的demo,在
StatusEnum
类型上实现了Stringer
接口,而不是*StatusEnum
。输出为:
请注意,现在第一个是
&{Disable}
。之前是&{1}