我是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的新手,想要了解问题.我看到它的方式,我有两个问题:
为什么不能成功转换这个东西?我查看了Go反射和sql包的源代码,并且有这种转换的方法,但它们似乎都失败了.这是一个错误吗?问题是什么?
我想sql.Scanner
通过实现以下方法可以实现接口:
Scan(src interface{}) error
我试图实现该方法,我甚至能够从中获取正确的值src
并将其转换为a FileType
,但是我很困惑,如果我应该为" (f *FileType)
或"实现该方法(f FileType)
.无论哪种方式调用该方法,但我不能覆盖f
(或至少更新后来丢失),File
从DB读取的实例总是有一个"0"作为值File.Type
.
你对这两点有什么想法吗?
我最近有同样的需求,解决方案是实现两个接口:
SQL/driver.Valuer
sql.Scanner
这是一个有效的例子:
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 }
稍微偏离主题,但可能对其他人有用,因为我在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 }