更新:好的,我弄错了。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更新:它不能工作,因为无法访问的字段
type User struct {
CustomJSONType
Id int
Name string
Email string
}但是,我不知道如何用IntList扩展CustomJSONType。我必须明确地为Scan和Value定义IntList。即使充其量,我也可以将Value和Scan的实现包装为独立的函数,但仍然必须在IntList中为Scan和Value编写签名。定义IntList的任何建议与User一样简单
发布于 2021-06-21 14:05:09
金刚没有“继承”的概念,只有结合。不喜欢普通的OOP语言,struct CustomJSONType无法访问来自IntList和User的数据,因此CustomJSONType.Value方法不能序列化除自身之外的其他类型。如果您想实现一个方法一次并在任何地方使用它,我提供了如下的想法。
package main
import (
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
)
type CustomJSONType struct {
data interface{}
}
func (t *CustomJSONType) Scan(src interface{}) error {
bytes, ok := src.([]byte)
if !ok {
return errors.New("invalid input type")
}
err := json.Unmarshal(bytes, t.data)
if err != nil{
return err
}
return nil
}
func (t CustomJSONType) Value() (driver.Value, error) {
bytes, err := json.Marshal(t.data)
if err != nil {
return []byte{}, err
}
return bytes, err
}
func (t CustomJSONType) GormDataType() string {
return "json"
}
type User struct {
Id int
Name string
Email string
}
type Project struct {
user CustomJSONType
}
func (p *Project) SetUser(u User) {
p.user.data = u
}
func (p *Project) GetUser() User {
user := p.user.data.(User)
return user
}发布于 2021-06-21 19:42:10
不知道我是否正确地理解了你。但是您可以组合几种类型,包括一个ints数组,而无需创建结构。它们仍然是一种类型,在功能上是可用的。但是组合类型需要一个结构,这就是为什么不能直接使用数组寻址。
type IntArr []int
type AnyStruct struct{
Uses bool
}
type TestIntArrStruct struct{
IntArr
AnyStruct
}
func(arr *IntArr) Add(i ...int){
*arr = append(*arr, i...)
}
func(anyStruct *AnyStruct) Invert(){
anyStruct.Uses = !anyStruct.Uses
}
var a TestIntArrStruct
a.Add(1,2,3)
a.Invert()你可以在这里看到它:https://play.golang.org/p/MF5eMcgmeak
https://stackoverflow.com/questions/68066495
复制相似问题