Go嵌入结构体结合接口使用失效,无法读写BaseEntity字段如何解决?
问题根因
这段代码无法修改BaseEntity的Id字段,核心原因是SetId方法使用了值接收者:
- Go中值接收者的方法执行时,会复制一份完整的接收者对象,方法内修改的是复制后的副本,不会对原对象产生任何影响
- 虽然
GetId用值接收者能正常读值,但SetId的修改完全不生效,才会导致调用SetId后GetId仍然返回空字符串
修正方案
只需要把BaseEntity的两个方法的接收者改成指针类型即可,修改后不管是基类还是组合的结构体都能正常读写字段,修正后的完整代码如下:
package main import "fmt" type BaseEntity struct { Id string } // 接收者改为指针类型,直接操作原对象 func (p *BaseEntity) SetId(Id string) { p.Id = Id } // 接收者也统一改为指针类型,保持方法集一致性 func (p *BaseEntity) GetId() string { return p.Id } type Employee struct { BaseEntity Name string } type DataInterface interface { SetId(Id string) GetId() string } func getObjFactory() DataInterface { return new(Employee) } func main() { entity := getObjFactory() entity.SetId("TEST") fmt.Printf(">> %s", entity.GetId()) // 运行输出 >> TEST }
额外说明
- Go没有传统面向对象的「继承」概念,这里
Employee嵌入BaseEntity属于结构体组合,嵌入结构体的方法会自动提升到外层结构体,不需要额外实现 - 当方法需要修改接收者的字段,或者接收者结构体体积较大时,统一使用指针接收者是Go的通用编码规范,也能避免不必要的值拷贝开销
内容的提问来源于stack exchange,提问作者Abhijit Desai
相关产品推荐
相关产品推荐

