ste*_*bez 3 comparison struct go
我有一个Favorites
带有切片字段的结构:
type Favorites struct {
Color string
Lunch string
Place string
Hobbies []string
}
Run Code Online (Sandbox Code Playgroud)
我有一个Person
包含其他结构的:
type Person struct {
Name string
Favorites Favorites
}
Run Code Online (Sandbox Code Playgroud)
我想看看该Favorites
字段是否设置在“人员”上。对于其他类型的字段,例如字符串或整数,我会将该字段与零值(分别为“”或 0)进行比较。
如果我尝试与下面的零进行比较,我会收到错误invalid operation: p2.Favorites == zeroValue (struct containing []string cannot be compared)
:
p2 := Person{Name: "Joe"}
zeroValue := Favorites{}
if p2.Favorites == zeroValue {
fmt.Println("Favorites not set")
}
Run Code Online (Sandbox Code Playgroud)
这与规范中定义的内容相匹配(https://golang.org/ref/spec#Comparison_operators)。
除了繁琐地比较每个字段(并且必须记住在结构发生变化时更新它)之外,还有什么办法可以进行这种比较吗?
一种选择是使“收藏夹”字段成为指向结构的指针而不是结构本身,然后仅与 nil 进行比较,但这是在一个大型代码库中,因此我不想在这种情况下进行可能影响深远的更改。
根据 this,您可以使用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)
}
Run Code Online (Sandbox Code Playgroud)
然后用以下方式调用它:
p2.Favorites.Equals(zeroValue)
Run Code Online (Sandbox Code Playgroud)