Go语言 接受任何结构的泛型结构

5uzkadbs  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(69)

如何创建一个接受任何结构的泛型结构?

package model

type model struct {
    m *interface{}
}

func (m *model) Select(){
    
}

type (
    field struct {
        table   string
        field   string
    }
    fields  map[string]field
)

type User struct {
    schema      string
    fields      fields
}

func NewUser() *interface{} {
    model_user := &User{
        schema: "main",
        
        fields: fields{
            "id":           field{"user","id"},
            "client_id":    field{"user","client_id"},
            "email":        field{"user","email"},
        },
    }
    return model(model_user)
}

主要

NewUser()

误差

cannot convert model_user (variable of type *User) to type model
c7rzv4ha

c7rzv4ha1#

正如定义的那样,model结构体的存在似乎是为了将Select()函数添加(或尝试添加)到模型中包含的值。
也就是说,你似乎想要某种类型,它提供了调用Select()的能力,并对任何类型的值执行某种操作(可能在Select()实现中使用某种形式的类型开关)。
如果是这样的话,那么你最好直接使用interface,消除model中间人:

type Selectable interface {
  Select()
}

type User struct {
  //...
}

func (u *User) Select() {
   // implement Select as appropriate for the User type
}

func NewUser() *User {
  return &User{
     // ...
  }
}

func Select(s Selectable) {
   s.Select()
}

func main() {
   u := NewUser()
   Select(u)
}

您会发现Select(Selectable)函数是多余的(您可以直接调用u.Select();提供它仅仅是为了说明在需要Selectable的情况下可以使用任何类型的值,只要该类型实现Selectable接口。
GoLang中的interfaces提供了duck-typing -如果一个类型实现了一个接口的契约,那么它就实现了这个接口,即使这个具体类型没有任何正式接口定义的先验知识。“如果它看起来像鸭子,嘎嘎叫像鸭子,那它就是鸭子。
如果意图是从User类型(或其他类型)中删除Select()ing的逻辑,并将其隔离在单独的“选择器”中,那么这可以通过删除model中介并简单地实现执行类型切换的func来实现:

func Select(v any) error {
   switch v := v.(type) {
      case *User:
         // ... implement for *User or call some private fn which encapsulates this behaviour
      default:
          return errors.New("value cannot be Select()ed")
    }
}

相关问题