Saya selalu menggunakan properti virtual pada dokumen dengan luwak di proyek node saya, dan ingin menggunakan mekanisme yang sama dalam proyek golang saya. Saya tidak dapat menemukan cara terbaik untuk mengimplementasikan sesuatu seperti ini.

Saya memiliki beberapa struct, diambil dari DB saya dan ingin menambahkan bidang berdasarkan konfigurasi server saya (seperti alamat IP, dll ...). Saya ingin menghindari memanggil fungsi yang sama setiap kali saya mengambil dokumen koleksi ini.

1
vmathieu 18 Desember 2017, 03:01

1 menjawab

Jawaban Terbaik

Paling mudah adalah dengan menambahkan metode ke struct yang menghitung nilai yang Anda inginkan, dan ketika Anda membutuhkannya, panggil metode itu.

Sebagai contoh:

type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
}

func (p *Person) Name() string {
    return p.FirstName + " " + p.LastName
}

func main() {
    p := &Person{FirstName: "Bob", LastName: "Archer"}
    fmt.Println(p.Name())
}

Keuntungannya adalah Name() akan selalu mengembalikan nama "benar" bahkan jika Anda mengubah nama depan atau belakang setelah mengambil dokumen.

Jika Anda ingin menghindari keharusan untuk selalu menghitung hasilnya, Anda dapat menyimpannya di sebuah bidang, misalnya:

type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
    name      string
}

func (p *Person) Name() string {
    if p.name == "" {
        p.name = p.FirstName + " " + p.LastName
    }
    return p.name
}

Perhatikan bahwa saat menyimpan nilai Person, bidang name tidak akan dipertahankan karena tidak diekspor.

Dan jika Anda ingin mengotomatisasi ini (misalnya Anda ingin name dihitung secara otomatis saat Anda mengambil dokumen dari MongoDB), Anda dapat menulis logika unmarshaling kustom Anda dengan menerapkan bson.Setter antarmuka. Logika unmarshaling khusus tidak akan istimewa, hanya menghitung dan menyetel bidang name setelah melakukan logika marshaling default.

Sebagai contoh:

type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
    name      string
}

func (p *Person) SetBSON(raw bson.Raw) (err error) {
    type my Person
    if err = raw.Unmarshal((*my)(p)); err != nil {
        return
    }
    p.name = p.FirstName + " " + p.LastName
    return nil
}

Dan jika Anda ingin bidang name diekspor, mis. Name, maka Anda dapat menggunakan nilai tag bson - untuk mengecualikan bidang ini agar tidak disimpan ke MongoDB, mis .:

type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
    Name      string `bson:"-"`
}
1
icza 18 Desember 2017, 10:17