首页 文章

如何在Google Datastore for Golang中忽略struct中的零值?

提问于
浏览
1

我正在尝试使用Google Datastore来存储Go的数据 . 由于 EndDate 是可选字段,并且不希望在该字段中存储零值 . 如果我为时间字段制作指针,Google Datastore将发送错误消息 - datastore: unsupported struct field type: *time.Time

如何忽略struct中的零值字段?

type Event struct {
    StartDate time.Time `datastore:"start_date,noindex" json:"startDate"`
    EndDate   time.Time `datastore:"end_date,noindex" json:"endDate"`
}

2 回答

  • 2

    默认保存机制不处理可选字段 . 字段要么一直保存,要么永远不保存 . 没有“只有在 Value 不等于某事时才能保存”这样的事情 .

    "optionally saved property"被视为自定义行为,自定义保存机制,因此必须手动实现 . Go的方法是在你的struct上实现PropertyLoadSaver接口 . 在这里,我提出了两种不同的方法来实现:

    手动保存字段

    下面是一个示例如何通过手动保存字段来实现(如果它是零值,则排除 EndDate ):

    type Event struct {
        StartDate time.Time `datastore:"start_date,noindex" json:"startDate"`
        EndDate   time.Time `datastore:"end_date,noindex" json:"endDate"`
    }
    
    func (e *Event) Save(c chan<- datastore.Property) error {
        defer close(c)
        // Always save StartDate:
        c <- datastore.Property{Name:"start_date", Value:e.StartDate, NoIndex: true}
    
        // Only save EndDate if not zero value:
        if !e.EndDate.IsZero() {
            c <- datastore.Property{Name:"end_date", Value:e.EndDate, NoIndex: true}
        }
        return nil
    }
    
    func (e *Event) Load(c chan<- datastore.Property) error {
        // No change required in loading, call default implementation:
        return datastore.LoadStruct(e, c)
    }
    

    使用另一个结构

    这是使用另一个结构的另一种方式 . Load() 实现始终相同,只有 Save() 不同:

    func (e *Event) Save(c chan<- datastore.Property) error {
        if !e.EndDate.IsZero() {
            // If EndDate is not zero, save as usual:
            return datastore.SaveStruct(e, c)
        }
    
        // Else we need a struct without the EndDate field:
        s := struct{ StartDate time.Time `datastore:"start_date,noindex"` }{e.StartDate}
        // Which now can be saved using the default saving mechanism:
        return datastore.SaveStruct(&s, c)
    }
    
  • 0

    在字段标记中使用omitempty . 来自文档:https://golang.org/pkg/encoding/json/

    Struct值编码为JSON对象 . 除非字段的标记为“ - ”,否则每个导出的struct字段都将成为对象的成员,或者字段为空且其标记指定“omitempty”选项 . Field int json:“myName,omitempty”

相关问题