文档:https://pkg.go.dev/github.com/google/go-cmp/cmp
与reflect.DeepEqual 相比,它提供了自定义比较方式,另外如果是在测试中,它可以返回可读性较高的两个值之间的差异。
Func
// Diff返回一个人类可读的关于两个值之间差异的报告:y - x。
// 当且仅当Equal对相同的输入值和选项返回true时,它返回一个空字符串。
func Diff(x, y interface{}, opts ...Option) string
// 它的行为与reflect.DeepEqual比较类似
// 基本数据类型,如bool,int,float,complex numbers,string, channel 相当于 '=='
// Func 只有两者都是 nil 时相等
// Struct 递归判断每个字段Equal,如果包含未导出字段且没有忽略它,或导致恐慌
// Slice 相同索引处的元素“深度”相等, non-nil 和 nil slice不相等
// Map key 指向的value 相等, non-nil 和 nil map不相等
// Pointer 两者存储的具体值“深度”相等
func Equal(x, y interface{}, opts ...Option) bool
package main
import (
"fmt"
"github.com/google/go-cmp/cmp"
)
type Persion struct {
Name string
Age uint
}
func main() {
p1 := Persion{"zhangsan",10}
p2 := Persion{"zhangsan",20}
diff := cmp.Diff(p1,p2)
fmt.Println(diff)
}
--------------------------------output-----------------------------------
main.Persion{
Name: "zhangsan",
- Age: 10,
+ Age: 20,
}
type Option
func AllowUnexported(types ...interface{}) Option // 允许比较指定的未导出类型
func Exporter(f func(reflect.Type) bool) Option // 允许对哪些未导出字段进行比较
/*
// 允许对所有未导出字段进行比较
diff := cmp.Diff(p1,p2,cmp.Exporter(func(r reflect.Type) bool {
return true
}))
*/
func Comparer(f interface{}) Option // 自定义比较器,f必须是 func(T, T) bool 类型
func Ignore() Option // 不进行比较
// FilterPath返回一个新的Option,只有f返回true时,opt才会生效
// 传入的选项可以是Ignore、Transformer、Comparer、Options或先前过滤过的option
func FilterPath(f func(Path) bool, opt Option) Option
type Path
type Path []PathStep
func (pa Path) GoString() string // 使用Go语法返回特定节点的路径
func (pa Path) Index(i int) PathStep
func (pa Path) Last() PathStep
func (pa Path) String() string
type PathStep
type PathStep interface {
String() string
Type() reflect.Type
Values() (vx, vy reflect.Value)
}
一个复杂的例子
func main() {
p1 := NewPersion("zhangsan",10)
p2 := NewPersion("zhangsan",20)
// 当匹配到指定的path,我们将其转交给cmp.Comparer 做比较
diff := cmp.Diff(p1,p2,cmp.FilterPath(func(path cmp.Path) bool {
fmt.Println(path.String())
fmt.Println(path.Last().String())
fmt.Println(path.GoString())
if path.String() == "Age" {
return true
}
return false
},cmp.Comparer(func(x,y uint) bool {
return true
})))
fmt.Println(diff)
}
--------------------------------output-----------------------------------
Name
.Name
{main.Persion}.Name
Age
.Age
{main.Persion}.Age