如何在Golang的Google数据存储区中忽略struct中的零值?

I am trying to use Google Datastore to store data by Go. Since the EndDate is optional field, and don't want to store zero value in that field. If I make a pointer for time field, Google Datastore will send an error message - datastore: unsupported struct field type: *time.Time

How can I ignore zero value field in struct?

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

The default saving mechanism does not handle optional fields. A field is either saved all the time, or never. There is no such thing as "only save if it's value does not equal to something".

The "optionally saved property" is considered a custom behavior, a custom saving mechanism, and as such, it has to be implemented manually. Go's way to do this is to implement the PropertyLoadSaver interface on your struct. Here I present 2 different methods to achieve that:

Manually saving fields

Here is an example how to do it by manually saving the fields (and excluding EndDate if it is the zero value):

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)
}

With another struct

Here's another way using another struct. The Load() implementation is always the same, only Save() differs:

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)
}

Use omitempty in the field tags. From the docs: https://golang.org/pkg/encoding/json/

Struct values encode as JSON objects. Each exported struct field becomes a member of the object unless

  • the field's tag is "-", or
  • the field is empty and its tag specifies the "omitempty" option.

Field int json:"myName,omitempty"