Answers:
您可以使用==与零值复合文字进行比较,因为所有字段都是可比较的:
if (Session{}) == session {
fmt.Println("is zero value")
}
由于存在歧义,因此在if条件下,在组合文字周围需要括号。
==
上面的用法适用于所有字段都是可比较的结构。如果结构包含不可比较的字段(切片,映射或函数),则必须将字段与它们的零值进行一一比较。
比较整个值的另一种方法是比较在有效会话中必须设置为非零值的字段。例如,如果在有效会话中玩家ID必须为!=“”,请使用
if session.playerId == "" {
fmt.Println("is zero value")
}
session
为非零*Session
,则使用if (Session{} == *session {
。
struct containing []byte cannot be compared
因为,好,我的结构包含一个字节片。
==
与切片字段进行比较将失败。为了比较这些结构,请使用reflect.DeepEqual
或考虑一些更专门的内容,例如此处讨论的内容:stackoverflow.com/questions/24534072/…–
这里还有3条建议或技巧:
您可以添加一个附加字段,以告知该结构是否已填充或为空。我故意命名它ready
,并不是empty
因为a的零值bool
是false
,所以如果您创建一个新的结构,如Session{}
它的ready
字段将自动出现false
,它将告诉您真相:该结构尚未准备好(它是空的)。
type Session struct {
ready bool
playerId string
beehive string
timestamp time.Time
}
初始化结构时,必须设置ready
为true
。isEmpty()
不再需要您的方法(尽管您可以根据需要创建一个方法),因为您可以只测试ready
字段本身。
var s Session
if !s.ready {
// do stuff (populate s)
}
bool
随着结构的变大或它包含不可比较的字段(例如,切片map
和函数值),此附加字段的意义也随之增加。
这与之前的建议类似,但是它使用现有字段的零值,当结构不为空时,该字段被视为无效。可用性取决于实现。
例如,如果在您的示例中您playerId
不能为空string
""
,则可以使用它来测试您的结构是否为空,如下所示:
var s Session
if s.playerId == "" {
// do stuff (populate s, give proper value to playerId)
}
在这种情况下,值得将此检查合并到isEmpty()
方法中,因为此检查取决于实现:
func (s Session) isEmpty() bool {
return s.playerId == ""
}
并使用它:
if s.isEmpty() {
// do stuff (populate s, give proper value to playerId)
}
第二个建议是对结构使用Pointer *Session
。指针可以具有nil
值,因此您可以对其进行测试:
var s *Session
if s == nil {
s = new(Session)
// do stuff (populate s)
}
使用reflect.deepEqual也可以,特别是当结构中有地图时
package main
import "fmt"
import "time"
import "reflect"
type Session struct {
playerId string
beehive string
timestamp time.Time
}
func (s Session) IsEmpty() bool {
return reflect.DeepEqual(s,Session{})
}
func main() {
x := Session{}
if x.IsEmpty() {
fmt.Print("is empty")
}
}
也许像这样
package main
import "fmt"
import "time"
type Session struct {
playerId string
beehive string
timestamp time.Time
}
func (s Session) Equal(o Session) bool {
if(s.playerId != o.playerId) { return false }
if(s.beehive != o.beehive) { return false }
if(s.timestamp != o.timestamp) { return false }
return true
}
func (s Session) IsEmpty() bool {
return s.Equal(Session{})
}
func main() {
x := Session{}
if x.IsEmpty() {
fmt.Print("is empty")
}
}