Go语言能否实现结构体中支持多种模型切片的泛型List字段?
问题解答
这个需求在Go 1.18及以上版本完全可以实现,借助Go的泛型特性就能完成和Java泛型类似的效果。
原写法的问题
你最初定义的[]*interface{}类型无法直接接收[]*model.SomeModel这类切片,因为在Go中,不同元素类型的切片属于完全不同的类型,即使*model.SomeModel可以赋值给interface{},对应的切片类型也不兼容,编译阶段就会报错。
泛型实现方案
给结构体增加类型参数即可实现通用的列表承载能力:
// T为泛型参数,约束为any表示可以接收任意类型作为列表元素的类型 type ResponseListDataPayload[T any] struct { List []*T `json:"list"` TotalCnt int64 `json:"totalCnt"` Page int64 `json:"page"` Step int64 `json:"step"` }
使用方式和你预期的完全一致,Go编译器会自动推导泛型参数类型:
// 接收[]*model.SomeModel类型 queryResults := []*model.SomeModel{} resposeResult := &ResponseListDataPayload{ List: queryResults, TotalCnt: cnt, Page: pageInt, Step: stepInt, }
// 接收[]*model.AnotherModel类型 queryResults := []*model.AnotherModel{} resposeResult := &ResponseListDataPayload{ List: queryResults, TotalCnt: cnt, Page: pageInt, Step: stepInt, }
这种写法会保留编译期类型校验,不需要手动做类型转换,JSON序列化/反序列化也完全正常。
1.18以下版本兼容方案
如果你使用的是不支持泛型的老版本Go,也可以把List字段声明为interface{}类型实现相同的赋值效果:
type ResponseListDataPayload struct { List interface{} `json:"list"` TotalCnt int64 `json:"totalCnt"` Page int64 `json:"page"` Step int64 `json:"step"` }
这种写法可以直接赋值任意类型的切片,JSON序列化也不受影响,缺点是取List的值时需要手动做类型断言,没有编译期类型校验。
内容的提问来源于stack exchange,提问作者armnotstrong
相关产品推荐
相关产品推荐

