go - Reflection.DeepEqual()返回false但 slice 相同

标签 go slice reflect

我正在比较两个均为[]int类型的 slice 。一种以json的形式进入API并解析为go struct。在结构中,它被初始化为空[]int{}。第二个保存在数据库(MongoDb)中,并提取并映射到相同的结构类型。
在某些情况下,两个 slice 完全空白。但是比较返回falsereflect.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")
    }
}
谢谢!

最佳答案

如果一个 slice 是reflect.DeepEqual(),而另一个 slice 是具有false长度的非nil slice ,则 nil 返回0。引用reflect.DeepEqual()的文档:

Slice values are deeply equal when all of the following are true: they are both nil or both non-nil, they have the same length, and either they point to the same initial entry of the same underlying array (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal. Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil)) are not deeply equal.


例子:
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
如果JSON或MongoDB源代码中不存在S1字段,则在将其编码后将保留为nil。但是,如果它以空数组形式存在,则会在Go中为其创建一个空的非nil slice 。
示例证明:
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

关于go - Reflection.DeepEqual()返回false但 slice 相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64643402/

相关文章:

windows - goapp 服务 : unable to find dev_appserver. py

go - go lang 中类似 slice 移位的函数

go - 使用 Go Reflect 按名称和参数调用方法

go - 在 golang 反射 FieldByName 中忽略大小写

go - GO中函数体错误之外的非声明语句

json - golang - 将结构格式化为 json

google-app-engine - Google App Engine 高性能代理解决方法

string - F# 中的表达式 "some string".[3 .. 7] 调用了哪个函数?

jQuery:一个接一个地淡入前 n 个子级

javascript - Eslint 无法识别 Reflect