reflect.DeepEqual() 返回 false 但切片相同

Ama*_*aur 1 go slice reflect

我正在比较两个切片,都是 type []int。一种是以json的形式进入API并解析为go struct的。在 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")
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

icz*_*cza 6

reflect.DeepEqual()返回false如果一个片是nil,另一个是非nil切片与0长度。引用自 doc 的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")
}
Run Code Online (Sandbox Code Playgroud)

此输出(在Go Playground上尝试):

not equal
Run Code Online (Sandbox Code Playgroud)

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

举例证明:

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)
Run Code Online (Sandbox Code Playgroud)

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

{[]} true
{[]} false
Run Code Online (Sandbox Code Playgroud)