I Go kan du ikke definere standardværdier for felter, de vil altid være nulværdien af deres type, når en ny strukturværdi oprettes (medmindre du bruger en sammensat literal, hvor du eksplicit kan angive en anden værdi).
Så en mulighed ville være at oprette en konstruktør-lignende funktion NewUser()
som ville sætte dette felt, og altid bruge denne funktion til at oprette nye brugere:
func NewUser() *User {
return &User{
CreatedAt: time.Now(),
}
}
Dette kan selvfølgelig ikke tvinges, og det vil også holde tidsstemplet for User
struct værdiskabelse og ikke når den er gemt.
En anden, bedre tilgang er at bruge en brugerdefineret rangeringslogik.
Du kan skrive tilpasset marshaling-logik ved at implementere bson.Getter
. GetBSON()
er ansvarlig for at angive en værdi, der rent faktisk vil blive gemt. Vi vil have den samme User
instans, der skal gemmes, kun dens CreatedAt
felt indstillet før:
type User struct {
CreatedAt time.Time `json:"created_at" bson:"created_at"`
}
func (u *User) GetBSON() (interface{}, error) {
u.CreatedAt = time.Now()
type my *User
return my(u), nil
}
Bemærk, at en ny my
type oprettes og returneres. Grunden til dette er at undgå stak overløb. Du skal blot returnere en værdi af typen *User
er dårlig, fordi den implementerer bson.Getter
, så GetBSON()
ville blive ringet op i det uendelige. Den nye my
type har ikke denne metode, så endeløs "rekursion" sker ikke (type
søgeord opretter en ny type, og det "arver" ikke metoder af den underliggende type).
Bemærk, at denne løsning også vil overskrive (nulstille) CreatedAt
felt), selvom du bare vil gemme en User
igen . Så vi bør tilføje et tjek om CreatedAt
felt er udfyldt, og indstil det kun, hvis det er nulværdien:
func (u *User) GetBSON() (interface{}, error) {
if u.CreatedAt.IsZero() {
u.CreatedAt = time.Now()
}
type my *User
return my(u), nil
}
Se også relateret/lignende spørgsmål:Få adgang til MongoDB fra Go