如何制作接受任何结构的通用结构?
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
根据定义,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
接口。
interfaces
提供鸭子类型 - 如果一个类型实现了接口的契约,那么它就实现了该接口,即使该具体类型事先不知道任何正式的接口定义。即“如果它看起来像鸭子并且嘎嘎叫起来像鸭子,那么它就是鸭子”。
如果目的是从 User
类型(或其他类型)中删除 Select()ing
的逻辑,并将其隔离在单独的“选择器”中,那么可以通过删除 model
中介并简单地实现一个 func 来再次实现这一点执行类型转换:
<code>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") } } </code>
以上是接受任何结构的通用结构的详细内容。更多信息请关注PHP中文网其他相关文章!