V Go nemůžete definovat výchozí hodnoty pro pole, vždy budou mít nulovou hodnotu svého typu, když se vytvoří nová hodnota struktury (pokud nepoužijete složený literál, kde můžete explicitně zadat jinou hodnotu).
Jednou z možností by tedy bylo vytvořit funkci podobnou konstruktoru NewUser()
které by nastavilo toto pole a k vytváření nových uživatelů vždy použijte tuto funkci:
func NewUser() *User {
return &User{
CreatedAt: time.Now(),
}
}
Samozřejmě to nelze vynutit a také to bude obsahovat časové razítko User
vytvoření hodnoty struktury a nikoli při jejím uložení.
Dalším, lepším přístupem je použití vlastní zařazovací logiky.
Vlastní zařazovací logiku můžete napsat implementací bson.Getter
. GetBSON()
je odpovědný za poskytnutí hodnoty, která bude skutečně uložena. Chceme stejného User
instance, která se má uložit, stačí její CreatedAt
pole nastavené před:
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
}
Všimněte si, že nový my
typ je vytvořen a vrácen. Důvodem je zabránit přetečení zásobníku. Jednoduše vrátí hodnotu typu *User
je špatný, protože implementuje bson.Getter
, takže GetBSON()
by byl volán donekonečna. Nový my
type tuto metodu nemá, takže nedochází k nekonečné "rekurzi" (type
klíčové slovo vytváří nový typ a „nedědí“ metody základního typu).
Všimněte si, že toto řešení také přepíše (resetuje) CreatedAt
pole), i když chcete pouze znovu uložit User
. Měli bychom tedy přidat kontrolu, zda CreatedAt
pole je vyplněno a nastavte jej pouze v případě, že má nulovou hodnotu:
func (u *User) GetBSON() (interface{}, error) {
if u.CreatedAt.IsZero() {
u.CreatedAt = time.Now()
}
type my *User
return my(u), nil
}
Viz také související / podobná otázka:Přístup k MongoDB z Go