拥有此表结构:
CREATE TABLE `tableName` (
`Id` int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Status` enum('pending','rejected','sent','invalid') NOT NULL,
`Body` varchar(255) NULL
) ENGINE='MyISAM' COLLATE 'utf8_general_ci';
我有这个(不完整)代码正常工作:
type StatusEnum string
const (
STATUS_PENDING StatusEnum = "pending"
STATUS_REJECTED StatusEnum = "rejected"
STATUS_SENT StatusEnum = "sent"
STATUS_INVALID StatusEnum = "invalid"
)
func (s *StatusEnum) Scan(src interface{}) error {
if src == nil {
return errors.New("This field cannot be NULL")
}
if stringStatus, ok := src.([]byte); ok {
*s = StatusEnum(string(stringStatus[:]))
return nil
}
return errors.New("Cannot convert enum to string")
}
func (s *StatusEnum) Value() (driver.Value, error) {
return []byte(*s), nil
}
type EmailQueue struct {
Id uint64
Status StatusEnum
Body sql.NullString
}
func Save (db *sql.DB) error {
_, err = db.Exec(
"UPDATE `tableName` SET `Status` = ?, `Body` = ? WHERE `id` = ?",
&eqi.Status,
eqi.Body,
eqi.Id,
)
return err
}
所以我的问题是:为什么我需要在&eqi.Status
上使用指针引用(db.Exec
)?
sql.NullString
和我的自定义StatusEnum
都没有在github.com/go-sql-driver/mysql
中实现,为什么会有区别?
如果我不使用指针引用(eqi.Status
),我收到此错误(抛出database/sql/convert.go):
sql: converting Exec argument #0's type: unsupported type emailqueue.StatusEnum, a string
我试图实现其他一些我发现没有运气的接口。
我使用sql.Scanner
和sql.driver.Valuer
接口实现了其他自定义类型,但问题是相同的。
我猜测struct
并输入继承差异,但我无法得到任何暗示...... :(
请帮助了解发生了什么。谢谢!!! :)
答案 0 :(得分:4)
您对StatusEnum
类型的Valuer interface实施操作*StatusEnum
。因此,当您将一个参数作为参数传递给Exec时,它仅作为指针才有意义,因为它只指向StatusEnum
实现Value()
的指针,需要内联参与。
您没有EmailList
类型的定义,因此我可以建议您更改给定的Valuer
界面。
func (s StatusEnum) Value() (driver.Value, error) {
return []byte(s), nil
}
这是标准库implements自定义可空类型。