如何创建接收含共享字段的泛型切片的方法?Go泛型问题
正确实现计算泛型切片总金额的Go函数
原代码存在以下几个问题:
- 函数调用名称不匹配:定义的函数是
AddItemsAlt,但main中调用的是AddItems - 类型不兼容:传入
cart([]Cloth类型切片)时,使用了接收Food类型的回调函数 - 变量重复声明:先通过
var check声明变量,后又用check :=重复定义
下面提供两种可行的实现方案:
方案一:修正回调函数的使用
保留原有的泛型函数结构,针对不同类型传入对应的回调,将int类型的价格转换为float64:
type Food struct { name string price float64 } type Cloth struct { name string price int } func AddItemsAlt[T Cloth | Food](objects []T, getUnit func(obj T) float64) float64 { sum := 0.0 for _, obj := range objects { sum += getUnit(obj) } return sum } func main() { check := []Food{{"Pizza", 6.23}, {"Hamburgesa", 7.99}, {"Tacos", 4.34}} cart := []Cloth{{"Player", 6}, {"Pants", 8}, {"Tacos de Futbol", 10}} // 计算Food总金额 foodTotal := AddItemsAlt(check, func(obj Food) float64 { return obj.price }) // 计算Cloth总金额,将int类型价格转为float64 clothTotal := AddItemsAlt(cart, func(obj Cloth) float64 { return float64(obj.price) }) println("Food total:", foodTotal) println("Cloth total:", clothTotal) }
方案二:使用泛型约束+接口方法(更优雅)
定义一个泛型约束接口,要求类型实现GetPrice() float64方法,这样泛型函数无需额外传入回调,直接调用方法即可完成计算:
// 定义泛型约束,要求类型必须实现GetPrice方法 type Pricer interface { GetPrice() float64 } type Food struct { name string price float64 } // Food实现Pricer接口的GetPrice方法 func (f Food) GetPrice() float64 { return f.price } type Cloth struct { name string price int } // Cloth实现Pricer接口的GetPrice方法,自动转换int为float64 func (c Cloth) GetPrice() float64 { return float64(c.price) } // 接收所有实现了Pricer约束的泛型切片 func CalculateTotal[T Pricer](items []T) float64 { sum := 0.0 for _, item := range items { sum += item.GetPrice() } return sum } func main() { check := []Food{{"Pizza", 6.23}, {"Hamburgesa", 7.99}, {"Tacos", 4.34}} cart := []Cloth{{"Player", 6}, {"Pants", 8}, {"Tacos de Futbol", 10}} println("Food total:", CalculateTotal(check)) println("Cloth total:", CalculateTotal(cart)) }
方案对比
- 方案一灵活度高,无需修改原有结构体,适合临时场景或无法修改结构体的情况
- 方案二更符合Go的接口设计理念,代码结构更简洁,扩展性更强(后续新增带价格的结构体,只需实现
GetPrice方法即可复用CalculateTotal函数)
内容的提问来源于stack exchange,提问作者arturfil
相关产品推荐
相关产品推荐

