首页 >后端开发 >Golang >为什么在 Go 中比较 `time.Time` 结构体和 `==` 有时会返回 `false`?

为什么在 Go 中比较 `time.Time` 结构体和 `==` 有时会返回 `false`?

Susan Sarandon
Susan Sarandon原创
2024-12-24 16:02:15522浏览

Why Does Comparing `time.Time` Structs with `==` Sometimes Return `false` in Go?

使用 ==

Time 结构比较的困惑考虑一个场景,您创建两个具有看似相同的日期和时间的 time.Time 结构价值观。然而,当使用相等运算符 (==) 比较这些结构时,令人惊讶的是,结果返回 false。这种现象可能令人费解,但原因在于 time.Time 结构体的底层实现。

在底层,Golang 中的 time.Time 结构体被定义为一个复合值。根据规范,当使用 == 比较结构体值时,它们的所有字段都必须是可比较的,包括非 nil 字段。 Time 结构由各种字段组成,例如秒、纳秒,以及重要的位置指针。

位置指针在时间结构相等中的作用

这个位置指针指向特定的位置对象,并用作时区或相对于 UTC 时间的偏移量的引用。当使用 == 比较两个时间结构时,比较不仅扩展到秒和纳秒,还扩展到它们保存的位置指针。当具有相同日期和时间值的两个时间结构引用不同的 Location 对象时,即使它们代表相同的位置,也会出现问题。在这种情况下,相等运算符会报告 false。

调试位置指针问题

要验证此行为,请考虑以下代码:

t1 := time.Date(2016, 4, 14, 1, 30, 30, 222000000, time.UTC)
t2 := time.Unix(0, t1.Sub(time.Date(1970, 1, 1, 0, 0, 0, 0, t1.Location())).Nanoseconds())

fmt.Println("Locations:", t1.Location(), t2.Location())
fmt.Printf("Location pointers: %p %p\n", t1.Location(), t2.Location())
fmt.Println("Locations equal:", t1.Location() == t2.Location())

此代码的输出演示了差异:位置相同,但它们引用的位置指针不同,导致相等运算符返回false。

解决问题:使用 UTC 或 In() 方法

确保两个时间结构根据其时间值而不是其位置指针被视为相等,有几个选项。首先,您可以在两个时间结构上调用 UTC() 方法,将其位置设置为 UTC。这确保它们共享相同的 Location 对象,从而通过相等比较。

或者,您可以使用 In() 方法将时间结构的 Location 显式设置为所需位置。通过为两个时间结构体的 In() 方法提供相同的位置作为参数,您可以在使用 == 运算符时保证它们相等。

结论

了解 time.Time 结构的复杂性,特别是 Location 指针的作用,对于正确比较 Go 中的时间值至关重要。通过考虑这些细微差别,开发人员可以确保其代码库中的时间比较准确且一致。

以上是为什么在 Go 中比较 `time.Time` 结构体和 `==` 有时会返回 `false`?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn