Go语言如何实现带DateLastModified字段的结构体slice/map通用过滤
Go通用时间过滤实现方案
根据你的需求,有两种主流实现方式,优先推荐Go 1.18以上的泛型方案,无性能损耗且类型安全:
方案1:泛型+接口约束(Go 1.18+ 推荐)
第一步:定义公共接口约束
首先定义统一的时间获取接口,所有带DateLastModified字段的结构体都实现该接口:
import "time" // 所有包含修改时间字段的结构体都要实现该接口 type HasModifiedTime interface { GetDateLastModified() time.Time } // 给Thing结构体实现接口 func (t Thing) GetDateLastModified() time.Time { return t.DateLastModified } // 给Thing2结构体实现接口,后续新增结构体同理 func (t Thing2) GetDateLastModified() time.Time { return t.DateLastModified }
第二步:实现通用过滤函数
分别实现切片和Map的通用过滤方法:
// 通用切片过滤 func FilterSliceOnTime[T HasModifiedTime](items []T, threshold time.Time) []T { filtered := make([]T, 0, len(items)) for _, item := range items { // 可根据需求调整过滤规则,比如换成Before、Equal等判断 if item.GetDateLastModified().After(threshold) { filtered = append(filtered, item) } } return filtered } // 通用Map过滤 func FilterMapOnTime[K comparable, V HasModifiedTime](items map[K]V, threshold time.Time) map[K]V { filtered := make(map[K]V, len(items)) for k, v := range items { if v.GetDateLastModified().After(threshold) { filtered[k] = v } } return filtered }
调用方式
完全符合你要求的调用形式,编译期自动校验类型:
// 切片过滤 filteredThings := FilterSliceOnTime(things, someTimeToFilterOn) filtered2Things := FilterSliceOnTime(thing2s, someTimeToFilterOn) // Map过滤 filteredThingsMap := FilterMapOnTime(thingsMap, someTimeToFilterOn) filtered2ThingsMap := FilterMapOnTime(thing2sMap, someTimeToFilterOn)
方案2:反射实现(兼容Go 1.18以下版本,不推荐)
如果需要兼容旧版本Go,可以用反射直接读取DateLastModified字段,缺点是性能差、类型不安全,结构体缺失对应字段会触发运行时错误:
import ( "reflect" "time" ) func FilterSliceOnTime(items interface{}, threshold time.Time) interface{} { val := reflect.ValueOf(items) if val.Kind() != reflect.Slice { panic("input must be slice") } res := reflect.MakeSlice(val.Type(), 0, val.Len()) for i := 0; i < val.Len(); i++ { item := val.Index(i) modTime := item.FieldByName("DateLastModified").Interface().(time.Time) if modTime.After(threshold) { res = reflect.Append(res, item) } } return res.Interface() }
调用时需要手动做类型断言,使用成本较高。
后续新增同字段结构体,只要实现HasModifiedTime接口即可直接复用过滤方法,无需修改过滤逻辑代码,完全消除冗余。
内容的提问来源于stack exchange,提问作者marc esher
相关产品推荐
相关产品推荐

