I Go kan du inte definiera standardvärden för fält, de kommer alltid att vara nollvärdet av sin typ när ett nytt strukturvärde skapas (såvida du inte använder en sammansatt literal där du explicit kan ange ett annat värde).
Så ett alternativ skulle vara att skapa en konstruktorliknande funktion NewUser()
som skulle ställa in det här fältet och alltid använda denna funktion för att skapa nya användare:
func NewUser() *User {
return &User{
CreatedAt: time.Now(),
}
}
Naturligtvis kan detta inte tvingas, och detta kommer också att hålla tidsstämpeln för User
strukturvärdeskapande och inte när det sparas.
Ett annat, bättre tillvägagångssätt är att använda en anpassad rangeringslogik.
Du kan skriva anpassad marshaling-logik genom att implementera bson.Getter
. GetBSON()
är ansvarig för att tillhandahålla ett värde som faktiskt kommer att sparas. Vi vill ha samma User
instans som ska sparas, bara dess CreatedAt
fält inställd före:
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
}
Observera att en ny my
typ skapas och returneras. Anledningen till detta är att undvika stackspill. Returnerar helt enkelt ett värde av typen *User
är dåligt eftersom det implementerar bson.Getter
, alltså GetBSON()
skulle bli uppringd oändligt. Den nya my
typ har inte den här metoden, så oändlig "rekursion" inträffar inte (type
nyckelordet skapar en ny typ och det "ärver" inte metoder av den underliggande typen).
Observera att den här lösningen också kommer att skriva över (återställa) CreatedAt
även om du bara vill spara en User
igen . Så vi bör lägga till en kontroll om CreatedAt
fältet är ifyllt och ställ bara in det om det är nollvärdet:
func (u *User) GetBSON() (interface{}, error) {
if u.CreatedAt.IsZero() {
u.CreatedAt = time.Now()
}
type my *User
return my(u), nil
}
Se även relaterad / liknande fråga:Få åtkomst till MongoDB från Go