Em Go você não pode definir valores padrão para campos, eles sempre serão o valor zero de seu tipo quando um novo valor de estrutura for criado (a menos que você use um literal composto onde você possa fornecer um valor diferente explicitamente).
Então, uma opção seria criar uma função do tipo construtor
NewUser()
que definiria este campo e usaria sempre esta função para criar novos usuários:func NewUser() *User {
return &User{
CreatedAt: time.Now(),
}
}
É claro que isso não pode ser forçado e também manterá o carimbo de data e hora do
User
struct criação de valor e não quando ele é salvo. Outra abordagem melhor é usar uma lógica de marshaling personalizada.
Você pode escrever uma lógica de marshaling personalizada implementando
bson.Getter
. GetBSON()
é responsável por fornecer um valor que será realmente salvo. Queremos o mesmo User
instância a ser salva, apenas seu CreatedAt
campo definido antes: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
}
Observe que um novo
my
tipo é criado e retornado. A razão para isso é evitar o estouro de pilha. Simplesmente retornando um valor do tipo *User
é ruim, porque implementa bson.Getter
, então GetBSON()
seria chamado sem parar. O novo my
type não tem este método, então a "recursão" infinita não acontece (o type
palavra-chave cria um novo tipo e não "herda" métodos do tipo subjacente). Observe que esta solução também substituirá (redefinirá) o
CreatedAt
campo) mesmo se você quiser apenas salvar novamente um User
. Portanto, devemos adicionar uma verificação se o CreatedAt
campo está preenchido, e só defina se for o valor zero:func (u *User) GetBSON() (interface{}, error) {
if u.CreatedAt.IsZero() {
u.CreatedAt = time.Now()
}
type my *User
return my(u), nil
}
Veja também a pergunta relacionada/semelhante:Acessando o MongoDB de Go