1

我正在比较两个切片,都是 type []int。一种是以 json 的形式进入 API 并被解析为 go struct。在结构中,它被初始化为 empty []int{}。第二个保存在数据库(MongoDb)中并被提取并映射到相同的结构类型。

在某些情况下,这两个切片是完全空白的。但是比较又回来了false

reflect.DeepEqual(oldSettings.S1, newSettings.S1)

我还使用 . 检查了两个字段类型reflect.TypeOf(newSettings.S1)。两者都在重新调整[]int

请考虑这个操场链接的结构示例。

https://play.golang.org/p/1JTUCPImxwq

type OldSettings struct {
    S1 []int
}

type NewSettings struct {
    S1 []int
}

func main() {
    oldSettings := OldSettings{}
    newSettings := NewSettings{}

    if reflect.DeepEqual(oldSettings.S1, newSettings.S1) == false {
        fmt.Println("not equal")
    } else {
        fmt.Println("equal")
    }
}

谢谢!

4

1 回答 1

7

reflect.DeepEqual()false如果一个切片是nil,而另一个切片是非nil切片,则返回0。引用 doc of reflect.DeepEqual():

当满足以下所有条件时,切片值是完全相等的:它们都是 nil 或都非 nil,它们具有相同的长度,并且它们指向同一底层数组的相同初始条目(即 &x[0 ] == &y[0]) 或其对应的元素(直到长度)非常相等。请注意,非 nil 空切片和 nil 切片(例如,[]byte{} 和 []byte(nil))并不完全相等。

例子:

oldSettings := OldSettings{S1: []int{}}
newSettings := NewSettings{}

if reflect.DeepEqual(oldSettings.S1, newSettings.S1) == false {
    fmt.Println("not equal")
} else {
    fmt.Println("equal")
}

这个输出(在Go Playground上试试):

not equal

如果S1您的 JSON 或 MongoDB 源中不存在该字段,则在解组后它将被留下nil。但是如果它作为一个空数组存在,nilGo 中会为它创建一个空的非切片。

证明它的例子:

var s struct {
    S1 []int
}

if err := json.Unmarshal([]byte(`{}`), &s); err != nil {
    panic(err)
}
fmt.Println(s, s.S1 == nil)

if err := json.Unmarshal([]byte(`{"S1":[]}`), &s); err != nil {
    panic(err)
}
fmt.Println(s, s.S1 == nil)

哪些输出(在Go Playground上尝试):

{[]} true
{[]} false
于 2020-11-02T10:08:28.697 回答