如何比较两个结构、切片或映射是否相等?

新手上路,请多包涵

我想检查两个结构、切片和映射是否相等。

但是我遇到了以下代码的问题。请参阅我在相关行的评论。

 package main

import (
    "fmt"
    "reflect"
)

type T struct {
    X int
    Y string
    Z []int
    M map[string]int
}

func main() {
    t1 := T{
        X: 1,
        Y: "lei",
        Z: []int{1, 2, 3},
        M: map[string]int{
            "a": 1,
            "b": 2,
        },
    }

    t2 := T{
        X: 1,
        Y: "lei",
        Z: []int{1, 2, 3},
        M: map[string]int{
            "a": 1,
            "b": 2,
        },
    }

    fmt.Println(t2 == t1)
    //error - invalid operation: t2 == t1 (struct containing []int cannot be compared)

    fmt.Println(reflect.ValueOf(t2) == reflect.ValueOf(t1))
    //false
    fmt.Println(reflect.TypeOf(t2) == reflect.TypeOf(t1))
    //true

    //Update: slice or map
    a1 := []int{1, 2, 3, 4}
    a2 := []int{1, 2, 3, 4}

    fmt.Println(a1 == a2)
    //invalid operation: a1 == a2 (slice can only be compared to nil)

    m1 := map[string]int{
        "a": 1,
        "b": 2,
    }
    m2 := map[string]int{
        "a": 1,
        "b": 2,
    }
    fmt.Println(m1 == m2)
    // m1 == m2 (map can only be compared to nil)
}

http://play.golang.org/p/AZIzW2WunI

原文由 leiyonglin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 685
2 个回答

您可以使用 reflect.DeepEqual ,或者您可以实现自己的功能(在性能方面比使用反射更好):

http://play.golang.org/p/CPdfsYGNy_

 m1 := map[string]int{
    "a":1,
    "b":2,
}
m2 := map[string]int{
    "a":1,
    "b":2,
}
fmt.Println(reflect.DeepEqual(m1, m2))

原文由 OneOfOne 发布,翻译遵循 CC BY-SA 3.0 许可协议

reflect.DeepEqual 经常错误地用于比较两个类似的结构,如您的问题所示。

cmp.Equal 是比较结构的更好工具。

要了解为什么反射是不明智的,让我们看一下 文档

如果结构值的相应字段(导出的和未导出的)深度相等,则结构值深度相等。

….

数字、布尔值、字符串和通道 - 如果使用 Go 的 == 运算符相等,则它们是深度相等的。

如果我们比较两个 time.Time 相同 UTC 时间的值, t1 == t2 如果它们的元数据时区不同,则将为假。

go-cmp 查找 Equal() 方法并使用它来正确比较时间。

例子:

 m1 := map[string]int{
    "a": 1,
    "b": 2,
}
m2 := map[string]int{
    "a": 1,
    "b": 2,
}
fmt.Println(cmp.Equal(m1, m2)) // will result in true

重要的提示:

使用 cmp.Equal 时要小心,因为它 可能会导致恐慌

它旨在仅用于测试,因为性能不是目标,如果无法比较值,它可能会恐慌。它的恐慌倾向意味着它不适合虚假恐慌可能致命的生产环境。

原文由 Cole Bittel 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题