如何使用r3labs/diff实现嵌套结构体整体diff比较
解决方案
完全可以实现该需求,github.com/r3labs/diff 库支持自定义类型比较逻辑,你只需要告知库将 Date 结构体作为原子值处理,不递归拆分内部字段即可,有两种常用实现方式:
方案1:为Date类型实现Equal方法(推荐)
该库会自动检测实现了Equal方法的类型,将其作为整体进行比较,不会递归遍历内部字段:
import "fmt" type Date struct { Year int Month int Day int } // 实现Equal方法,diff库会优先调用该方法判断两个Date是否相等 func (d Date) Equal(other interface{}) bool { o, ok := other.(Date) if !ok { return false } return d.Year == o.Year && d.Month == o.Month && d.Day == o.Day } // 可选:实现String方法,变更日志打印时会自动格式化为2021-10-09格式 func (d Date) String() string { return fmt.Sprintf("%d-%02d-%02d", d.Year, d.Month, d.Day) }
修改后你原有调用diff.Diff的代码不需要做任何改动,得到的变更日志就会仅包含DateOfBirth的整体变更记录。
方案2:调用Diff时传入自定义比较器
如果你不想修改原有Date类型的定义,可以在调用比较方法时临时注册Date类型的比较逻辑:
cl, err := diff.Diff( Student{DateOfBirth: Date{2021, 11, 13}}, Student{DateOfBirth: Date{2021, 10, 9}}, // 注册Date类型的自定义比较函数 diff.WithComparer(func(a, b Date) bool { return a.Year == b.Year && a.Month == b.Month && a.Day == b.Day }), )
该方案的效果和方案1完全一致,仅适用于不需要全局复用Date比较逻辑的场景。
内容的提问来源于stack exchange,提问作者theshinylight
相关产品推荐
相关产品推荐

