仅基于接口而不考虑底层类型来比较字段的惯用方法是什么(没有“cmpopts.UseInterfaceOnly()”)?

问题描述 投票:0回答:1

我有一堆数据结构都遵循一个接口,我想编写一个可以在所有实现上工作的单元测试。

在这种情况下,如果我使用相同的结构类型,我想使用 cmp.Diff,但我找不到告诉 cmp 根据界面表面进行比较的方法。

玩具示例:

type Person interface {
    Name() string
    Age() int
}

type yearlyPerson struct {
    name     string
    yearsOld int
}

type dailyPerson struct {
    name    string
    daysOld int
}

func (dp *dailyPerson) Age() int {
    return dp.daysOld / 365
}

// Other 3 functions are trivial field returns.

如果我们假装有很多这样的字段,在单元测试中,我可能想使用

cmp.Diff
来很好地捕捉和显示它发现的任何差异,但是 IIUC,
cmp
只关注具体类型。

是否有一种惯用的方法来进行基于接口字段的比较?我没仔细看,但我还没有找到“cmp/cmpopts but for interface surfaces specifically”库。

在我的脑海中,我能想到的最好的是一个帮助库,它手动构造一个具体类型,其中导出的字段与界面表面匹配,然后相应地使用

cmp.Diff
,就像我在这里做的那样:https:// go.dev/play/p/TtEomRGXTtQ

这是最好的方法,还是有更好的方法?

go
1个回答
0
投票

您可以添加自定义 cmp.Comparer 选项以使用

reflect
比较基础类型,即

opt := cmp.Comparer(func(x, y reflect.Type) bool { return x == y })
cmp.Equal(d1, d2, opt)

定义一个断言为真的选项,如果基础类型相同,它可以与 cmp.Equal as

一起使用

去玩-https://go.dev/play/p/bNocWVz7EJe

© www.soinside.com 2019 - 2024. All rights reserved.