【发布时间】:2021-06-21 10:42:54
【问题描述】:
更新:好吧,我弄错了。 CustomJSONType 的函数无法访问它所嵌入的结构的字段,User 和 IntList 都应该定义自己的 Scan 和 Value 或尝试其他解决方法。
原帖于 2021-6-21
我正在使用 GORM 并尝试定义一些自定义类型,例如 User 和 IntList。
type User struct {
Id int
Name string
Email string
}
type IntList []int
众所周知,GORM 自定义类型必须实现 Value 和 Scan 函数。这就是我所做的——我定义了一个CustomJSONType,它实现了Value和Scan,如下所示:
type CustomJSONType struct {}
func (t *CustomJSONType) Scan(src interface{}) error {
bytes, ok := src.([]byte)
if !ok {
return errors.New("invalid input type")
}
err := json.Unmarshal(bytes, t)
if err != nil{
return err
}
return nil
}
func (t CustomJSONType) Value() (driver.Value, error) {
bytes, err := json.Marshal(t)
if err != nil {
return []byte{}, err
}
return bytes, err
}
func (t CustomJSONType) GormDataType() string {
return "json"
}
要为User 配备Value 和Scan,我所要做的就是在User 的定义中添加一行:
更新:由于CustomJSONType 无法访问User 的字段,它将无法工作
type User struct {
CustomJSONType
Id int
Name string
Email string
}
但是,我不知道如何用CustomJSONType 扩展IntList。我必须为IntList 明确定义Scan 和Value。即使充其量我可以将Value 和Scan 的实现包装为独立的函数,但仍然必须在IntList 中为Scan 和Value 编写签名。将IntList 定义为与User 一样简单的任何建议?
【问题讨论】:
-
结构类型是唯一允许嵌入的具体类型。由于
IntList不是结构类型,因此您不能像为User那样在其中嵌入CustomJSONType。 -
你想用 empty 结构类型上的
Scan和Value实现来完成什么?如果您希望CustomJSONType“继承”它所嵌入的结构的字段,那么您应该知道这不是嵌入所做的。在 Go 中没有类型扩展。 -
基本上你必须为这两种类型显式定义
Scan和Value-IntList和User。CustomJSONType没用,它所做的只是满足一个接口,但实现什么也不做,因为这两种方法中的t都是 empty 结构或指向空结构的指针。 -
@mkopriva 谢谢!我没有在运行时测试我的代码。
-
@mkopriva 您可以通过将空值结构作为第一个成员嵌入一个带有指针接收器的方法来伪造 Go 中的方法扩展,您可以在其中使用
unsafe.Pointer将接收器的类型更改为您的结构嵌入。至少在 Go 2 之前:github.com/golang/go/issues/18617 不推荐,但它有效。