Di Go, Anda tidak dapat menentukan nilai default untuk bidang, nilai tersebut akan selalu menjadi nilai nol dari jenisnya saat nilai struct baru dibuat (kecuali jika Anda menggunakan literal gabungan di mana Anda dapat memberikan nilai yang berbeda secara eksplisit).
Jadi satu opsi adalah membuat fungsi seperti konstruktor NewUser()
yang akan menyetel bidang ini, dan selalu gunakan fungsi ini untuk membuat pengguna baru:
func NewUser() *User {
return &User{
CreatedAt: time.Now(),
}
}
Tentu saja ini tidak bisa dipaksakan, dan ini juga akan menahan stempel waktu User
pembuatan nilai struct dan bukan saat disimpan.
Pendekatan lain yang lebih baik adalah menggunakan logika marshaling khusus.
Anda dapat menulis logika marshaling khusus dengan menerapkan bson.Getter
. GetBSON()
bertanggung jawab untuk memberikan nilai yang benar-benar akan disimpan. Kami menginginkan User
yang sama contoh yang akan disimpan, cukup CreatedAt
set bidang sebelumnya:
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
}
Perhatikan bahwa my
. baru jenis dibuat dan dikembalikan. Alasan untuk ini adalah untuk menghindari stack overflow. Cukup mengembalikan nilai tipe *User
buruk, karena mengimplementasikan bson.Getter
, jadi GetBSON()
akan dipanggil tanpa henti. my
. yang baru type tidak memiliki metode ini, jadi "rekursi" tanpa akhir tidak terjadi (type
kata kunci membuat jenis baru, dan tidak "mewarisi" metode dari jenis yang mendasarinya).
Perhatikan bahwa solusi ini juga akan menimpa (menyetel ulang) CreatedAt
field) bahkan jika Anda hanya ingin menyimpan ulang User
. Jadi kita harus menambahkan tanda centang apakah CreatedAt
bidang diisi, dan hanya atur jika nilainya nol:
func (u *User) GetBSON() (interface{}, error) {
if u.CreatedAt.IsZero() {
u.CreatedAt = time.Now()
}
type my *User
return my(u), nil
}
Lihat juga pertanyaan terkait/serupa:Mengakses MongoDB dari Go