如何将一个包含切片的结构体与零值结构体进行比较?

3

我有一个带有切片字段的Favorites结构体:

type Favorites struct {
    Color string
    Lunch string
    Place string
    Hobbies []string 
}

我有一个包含另一个结构体的Person

type Person struct {
    Name string
    Favorites Favorites
}

我想确认在“Person”上是否设置了“Favorites”字段。对于其他类型的字段,例如字符串或整数,我会将该字段与零值(""或0)进行比较。
如果我尝试像下面这样与零比较,我会收到错误信息“invalid operation: p2.Favorites == zeroValue(包含[]string的结构体无法进行比较):”。
p2 := Person{Name: "Joe"}

zeroValue := Favorites{}
if p2.Favorites == zeroValue {
    fmt.Println("Favorites not set")
}

这与规范中所定义的相符 (https://golang.org/ref/spec#Comparison_operators)。
有没有其他方法可以进行比较,而不是繁琐地比较每个字段(并且必须记住在结构体更改时进行更新)?
一种选择是将Favorites字段指向结构体的指针而不是结构体本身,然后只需与nil进行比较,但这是在一个大型代码库中,因此在这种情况下我宁愿不做可能影响广泛的更改。 https://play.golang.org/p/d0NSp8eBes

您能解释一下为什么不将 Favorites 字段设置为指针吗?如果您不关心等价性,仅仅是想验证该字段是否已设置,则似乎这是最佳选择。 - dalton_c
1
在我的上一条评论中,我建议小心使用零值来表示其他类型的“未设置”。0可能是int字段的完全有效值。 - dalton_c
@daltonclaybrook 这通常是最好的选择。在一个大型代码库中,如果结构体被广泛使用,我更关心进行更改。此外,如果结构体中有许多结构体字段,似乎如果我将其中一个更改为指针,则为了保持一致性,我应该可能更改所有字段。 - stephenbez
1个回答

5
根据这篇文章,你可以使用reflect.DeepEqual(),但最好自己编写一个函数:
type Favorites struct {
    Color string
    Lunch string
    Place string
    Hobbies []string 
}

func (favs *Favorites) Equals(other *Favorites) bool {
    color_eq := favs.Color == other.Color
    lunch_eq := favs.Lunch == other.Lunch
    place_eq := favs.Place == other.Place
    hobbies_eq := len(favs.Hobbies) == len(other.Hobbies)
    if hobbies_eq {  // copy slices so sorting won't affect original structs
        f_hobbies := make([]string, len(favs.Hobbies))
        o_hobbies := make([]string, len(other.Hobbies))
        copy(favs.Hobbies, f_hobbies)
        copy(other.Hobbies, o_hobbies)
        sort.Strings(f_hobbies)
        sort.Strings(o_hobbies)
        for index, item := range f_hobbies {
            if item != o_hobbies[index] {
                hobbies_eq = false
            }
        }
    }
    return (color_eq && lunch_eq && place_eq && hobbies_eq)
}

然后通过以下方式调用:

p2.Favorites.Equals(zeroValue)

需要在比较数组值之前对数组进行排序吗? - Alex Kroll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接