英文:
Constraint with setter methods to be used in other generic types
问题
我正在使用golang泛型进行实验,尝试在所有mongo集合上实现CRUD操作,但是在尝试直接在结构体上更新某些字段时遇到了问题,我得到了一个错误。
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没有实现TModel(SetName方法具有指针接收器)
我尝试将func(s *MyUser)
更改为func (s MyUser)
,但是结构体没有反映出更改。
Playground: https://go.dev/play/p/GqKmu_JfVtC
英文:
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
答案1
得分: 2
你在接口中设置了一个类型约束:
type TModel interface {
MyUser | AnotherModel
...
}
因此,你不能将*MyUser
作为TModel
的类型参数。
要修复编译时错误:更改类型约束
type TModel interface {
*MyUser | *AnotherModel
...
}
https://go.dev/play/p/1oP2LzeqXIa
额外的备注:除非你有特殊动机要明确列出可以用作TModel
的唯一类型,否则我认为
type TModel interface {
SetName(s string)
}
对于你的泛型类型来说可能已经足够了。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论