Go 在使用泛型时无法与 Pointer Receiver 共存的解决方法
问题描述
在使用 Go 的泛型时,如果泛型类型存在 constraint,而传入的类型在实现这个 constraint 时使用的是 pointer receiver,那么就会遇到 XXX does not satisfy XXX (method XXX has pointer receiver) 的报错,就比如下面这个例子希望用 Create 函数完成所有创建 Person 的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type Person interface {
SetID(id int)
}
type Student struct {
ID int
}
func (p *Student) SetID(id int) {
p.ID = id
}
func Create[T Person](id int) *T {
var person T
person.SetID(id)
return &person
}
这里 Student 用 (p *Student) 实现了 Person,然而如果用 Create[Student](id) 这种方式调用时,编译会遇到这个报错
1
Student does not satisfy Person (method SetID has pointer receiver)
问题解释
问题就在于这段代码中的 (p *Student)
1
2
3
func (p *Student) SetID(id int) {
p.ID = id
}
在 Go 中会认为是 *Student 实现了 SetID 方法,或者说实现了 Person interface,而不是 Student,因此提示 Student 并不满足 Person。
那一个办法是把实现 interface 传入的改成 value receiver
1
2
3
func (p Student) SetID(id int) { // 传入的 p 类型去掉了 *
p.ID = id
}
这样可以通过编译且正常运行,但问题是变成了值传递后,SetID 并不会作用于传入的那个变量,这个函数也形同虚设。
另一个解决方案是可以把调用函数时改成 Create[*Student](1),加上这个 *,报错也会随之消除。但问题就解决了吗?...
剩余内容已隐藏