I'm playing with golang generics, trying to implement CRUD operations over all the mongo collections, but I'm facing issues trying to update some fields directly on the struct but I'm getting an error
package main
import (
"fmt"
)
type TModel interface {
MyUser | AnotherModel
SetName(string)
}
type MyUser struct {
ID string `bson:"_id"`
Name string `bson:"name"`
}
type AnotherModel struct {
ID string `bson:"_id"`
Name string `bson:"name"`
}
// Using this function compiles, but never update the struct
func (s MyUser) SetName(name string) {
s.Name = name
}
/*This should be the right way, but fails at compile time */
/*
func (s *MyUser) SetName(name string) {
s.Name = name
}
*/
type Crud[model TModel] interface {
UpdateObj(m model) (*model, error)
}
type CrudOperations[model TModel] struct {
}
func (c *CrudOperations[model]) UpdateObj(m model) error {
fmt.Printf("\n Obj: %v", m)
m.SetName("NewName")
fmt.Printf("\n Obj: %v", m)
return nil
}
func main() {
c := CrudOperations[MyUser]{}
m := MyUser{Name: "Initial-Name"}
c.UpdateObj(m)
}
./prog.go:44:22: MyUser does not implement TModel (SetName method has pointer receiver)
I tried changing from func(s *MyUser)
to func (s MyUser)
but then the struct is not reflecting the change
ineffective assignment to field MyUser.Name (staticcheck)
Playground: https://go.dev/play/p/GqKmu_JfVtC
CodePudding user response:
You put a type constaint :
type TModel interface {
MyUser | AnotherModel
...
in your interface, so you can't use a *MyUser
as a type parameter for TModel
To fix your compile time error : change the type constraint
type TModel interface {
*MyUser | *AnotherModel
...
}
https://go.dev/play/p/1oP2LzeqXIa
one extra remark : unless you have an ulterior motive to explicitly list the only types that can ever be used as a TModel
, I would say that
type TModel interface {
SetName(s string)
}
is probably enough of a constraint for your generic type.