我是Go的新手,我正在尝试编写一个小程序来将枚举值保存到数据库中。 我声明我的值的方式如下:
type FileType int64
const (
movie FileType = iota
music
book
etc
)
我在我的结构中使用这些值,如下所示:
type File struct {
Name string
Type FileType
Size int64
}
我使用gorp作为我的数据库内容,但我猜gorp的使用与我的问题无关。我把东西放在我的数据库中这样:
dbmap.Insert(&File{"MyBook.pdf",movie,1000})
但是当我尝试检索东西时......
dbmap.Select(&dbFiles, "select * from Files")
我收到以下错误:
panic: reflect.Set: value of type int64 is not assignable to type main.FileType
当我使用int64
作为const(...)
和File.Type
字段的类型时,一切正常,但我是Go的新手,想要了解问题。
我看待它的方式,我有两个问题:
我想通过实现以下方法可以实现sql.Scanner
接口:
Scan(src interface{}) error
我尝试实现该方法,我甚至能够从src
获取正确的值并将其转换为FileType
,但如果我应该为“{{{ 1}}或(f *FileType)
。无论哪种方式调用该方法,但是我无法覆盖(f FileType)
(或者至少后来更新丢失)并且f
实例从数据库的File
值始终为“0”。
你对这两点有什么想法吗?
答案 0 :(得分:26)
我最近有同样的需求,解决方案是实现两个接口:
这是一个有效的例子:
type FileType int64
func (u *FileType) Scan(value interface{}) error { *u = FileType(value.(int64)); return nil }
func (u FileType) Value() (driver.Value, error) { return int64(u), nil }
答案 1 :(得分:8)
稍微偏离主题,但可能对其他人有用,因为在golang中使用postgres枚举字段(以字节形式返回)时解决类似问题时我一直在重新审视此问题/答案。
// Status values
const (
incomplete Status = "incomplete"
complete Status = "complete"
reject Status = "reject"
)
type Status string
func (s *Status) Scan(value interface{}) error {
asBytes, ok := value.([]byte)
if !ok {
return errors.New("Scan source is not []byte")
}
*s = Status(string(asBytes))
return nil
}
func (s SubjectStatus) Value() (driver.Value, error) {
// validation would go here
return string(s), nil
}
答案 2 :(得分:0)
(f FileType)
比(f *FileType)
便宜,而#34;本地"类型,除非你有一个复杂的类型,否则几乎总是更好地不使用指针。