可能是 golang 初学者的问题:)尝试编译下面的代码时,我遇到了以下编译器错误。我想为共享公共 ID 字段的不同类型(这里是 A 和 B)实现一个对象存储。按照 DRY 的想法,我想使用泛型来实现商店。添加一个对象时,我想使用GS接口设置它的ID字段(当然实际代码要复杂一些),但是编译器不希望我这样做。./prog.go:29:7: item.SetId 未定义(type *T 是指向类型参数的指针,而不是类型参数)./prog.go:34:24: A没有实现GS(SetId方法有指针接收者)有推荐的方法来解决这个问题吗?提前致谢!!package mainimport "fmt"type A struct { ID string AMember string}type B struct { ID string BMember string}type GS interface { Id() string SetId(string)}func (s A) Id() string { return s.ID }func (s *A) SetId(i string) { s.ID = i }func (s B) Id() string { return s.ID }func (s *B) SetId(i string) { s.ID = i }type MyStore[T GS] struct { values map[string]*T}func (s *MyStore[T]) add(item *T) { item.SetId("aa") s.values["aa"] = item}func main() { var storeA = &MyStore[A]{} storeA.values = make(map[string]*A) a := &A{} storeA.add(a) fmt.Println(a.Id())}
1 回答
侃侃尔雅
TA贡献1801条经验 获得超15个赞
关于使用 *T
简而言之,类型参数不是它的约束。该约束仅确定 上可用的操作T
,它并不暗示关于 的任何内容*T
,它现在只是一个未命名的指针类型。这是意义:
type *T 是指向类型参数的指针,而不是类型参数
因此,与您的情况一样,方法集*T
不会自动包含在T
具体类型上声明的指针接收器方法A
,并且它不会实现将由 实现的接口*A
。
您必须通过设置额外的约束将其明确告知编译器。在简化形式中,它类似于:
func Foo[T any, PT interface { SetId(string); *T}](v T) {}
您可以在此处找到有关此用例的更多示例和变体:
关于实施约束
&MyStore[A]{}
错误消息清楚地报告了此实例化失败的原因:
A没有实现GS(SetId方法有指针接收者)
换句话说SetId()
,声明于*A
,而不是A
。因此你应该实例MyStore
化*A
:
var storeA = &MyStore[*A]{}
然后*T
将结构/方法定义中的出现更改为T
:
type MyStore[T GS] struct { values map[string]T // just T instead of *T } func (s *MyStore[T]) add(item T) { }
在使用字段类型实例化时,*A
将变得等效于map[string]*A
因此使分配storeA.values = make(map[string]*A)
有效,并且方法签名add(item *A)
因此允许storeA.add(&A{})
.
固定游乐场:https ://gotipplay.golang.org/p/dcUVJ5YQK_b
- 1 回答
- 0 关注
- 88 浏览
添加回答
举报
0/150
提交
取消