I've a generic Repository that could be used for multiple structs (that hopefully extends Model
), currently it is defined Repository[M any]
.
Because M
is of type any
, I can't access Model
's fields without reflection. I couldn't figure out a way of defining something like Repository[M extends Model]
. I know that I won't be able to access SomeModel
and SomeOtherModel
fields without casting/reflection, but those are not relevant at the moment.
I want to keep it generic to leverage retrieval methods, i.e.: FindBy
and return the correct typing upstream.
Note: I understand that Go doesn't have inheritance and works via composition, I'm using the word "extends" just as a reference.
Playground: https://go.dev/play/p/Jwk7XxoDu1o
Code:
package main
import "reflect"
type Model struct {
Id string
// ... other generic fields
}
// Generic Repository used by multiple models
type Repository[M any] struct {
}
func (r *Repository[M]) FindBy(id string) (*M, error) {
model := new(M)
return model, nil
}
func (r *Repository[M]) Update(model M) {
// HERE: How to access model.Id without reflection?
}
// Multiple "Model" Impl
type SomeModel struct {
Model
}
type SomeOtherModel struct {
Model
}
func main() {
repo1 := &Repository[SomeModel]{}
someModel, _ := repo1.FindBy("1")
repo1.Update(*someModel)
repo2 := &Repository[SomeOtherModel]{}
someOtherModel, _ := repo2.FindBy("1")
repo2.Update(*someOtherModel)
println(reflect.TypeOf(*someModel).Name(), reflect.TypeOf(*someOtherModel).Name())
}