如何在Go语言中让多个结构体复用同一函数?
解决方案:利用Go结构体嵌入实现通用逻辑
在Go里,你可以通过**结构体嵌入(组合)**来实现只写一次通用函数,同时满足修改结构体的需求,完全不需要定义接口。具体步骤如下:
- 提取公共字段到基础结构体
把两个模型中重复的choices、cursor、selected字段抽成独立的基础结构体,所有需要复用逻辑的结构体都嵌入它:
type CommonModel struct { choices []string cursor int selected string } type ModelA struct { CommonModel // 嵌入公共结构体 name string } type ModelB struct { CommonModel // 嵌入公共结构体 year int }
- 给基础结构体的指针编写通用方法
因为你需要更新结构体,所以方法接收者必须是指针类型,这样修改才会作用到原结构体上:
import "fmt" func (m *CommonModel) CommonFunction(originalString string, question string) string { originalString += question // 遍历选项 for idx, choice := range m.choices { // 判断光标位置 cursor := " " if m.cursor == idx { cursor = ">" } // 判断是否选中 checked := " " if m.selected == choice { checked = "x" } // 拼接行内容 originalString += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice) } originalString += "\nPress ctrl + q to quit.\n" return "\n" + originalString + "\n\n" }
- 直接在ModelA/ModelB的指针实例上调用方法
由于Go的嵌入特性,基础结构体的方法会被"提升"到外层结构体,你可以直接用ModelA或ModelB的指针调用CommonFunction,方法内部会直接操作外层结构体的公共字段:
func main() { a := &ModelA{ CommonModel: CommonModel{ choices: []string{"Option 1", "Option 2"}, cursor: 0, selected: "Option 1", }, name: "Test Model A", } result := a.CommonFunction("Choose an option:\n", "") fmt.Println(result) // 修改cursor,会直接作用到原结构体 a.cursor = 1 result = a.CommonFunction("Choose an option:\n", "") fmt.Println(result) }
关键说明
- 指针接收者:必须用
*CommonModel作为方法接收者,这样在方法内部修改m.cursor、m.selected等字段时,会直接修改原结构体的内容,满足你更新结构体的需求。 - 无接口依赖:不需要定义任何接口,仅通过结构体嵌入就实现了逻辑复用,完全符合你的要求。
- 字段提升:嵌入后,
ModelA和ModelB的实例可以直接访问choices、cursor等公共字段,和直接定义在自身结构体里的用法完全一致。
内容的提问来源于stack exchange,提问作者Kia Martinez
相关产品推荐
相关产品推荐

