W Go nie możesz zdefiniować domyślnych wartości pól, zawsze będą one wartością zerową swojego typu, gdy tworzona jest nowa wartość struktury (chyba że używasz literału złożonego, w którym możesz jawnie podać inną wartość).
Jedną z opcji byłoby utworzenie funkcji podobnej do konstruktora NewUser()
który ustawi to pole i zawsze używa tej funkcji do tworzenia nowych użytkowników:
func NewUser() *User {
return &User{
CreatedAt: time.Now(),
}
}
Oczywiście nie można tego wymusić, a ponadto będzie to zawierało znacznik czasu User
struct tworzenia wartości, a nie kiedy jest zapisywana.
Innym, lepszym podejściem jest użycie niestandardowej logiki kierowania.
Możesz napisać niestandardową logikę kierowania, implementując bson.Getter
. GetBSON()
jest odpowiedzialny za dostarczenie wartości, która zostanie faktycznie zapisana. Chcemy tego samego User
instancja do zapisania, po prostu jej CreatedAt
pole ustawione wcześniej:
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
}
Zwróć uwagę, że nowy my
typ jest tworzony i zwracany. Powodem tego jest uniknięcie przepełnienia stosu. Wystarczy zwrócić wartość typu *User
jest zły, ponieważ implementuje bson.Getter
, więc GetBSON()
zostanie wywołany bez końca. Nowy my
typ nie ma tej metody, więc nieskończona "rekurencja" nie ma miejsca (type
słowo kluczowe tworzy nowy typ i nie „dziedziczy” metod typu bazowego).
Zauważ, że to rozwiązanie również nadpisze (zresetuje) CreatedAt
pole) nawet jeśli chcesz tylko ponownie zapisać User
. Powinniśmy więc dodać sprawdzenie, czy CreatedAt
pole jest wypełnione i ustaw je tylko wtedy, gdy jest to wartość zero:
func (u *User) GetBSON() (interface{}, error) {
if u.CreatedAt.IsZero() {
u.CreatedAt = time.Now()
}
type my *User
return my(u), nil
}
Zobacz także powiązane / podobne pytanie:Dostęp do MongoDB z Go