Saya menggunakan https://github.com/lib/pq untuk mendapatkan data daripada postgres. Untuk mengekstrak data saya menggunakan struktur pihak ketiga yang mengandungi medan cap waktu protobuf https://pkg.go.dev/google.golang.org/protobuf/types/known/timestampb#timestamp jadi Jadi masalahnya adalah untuk mendapatkan kerja untuk mengimbas dari masa.masa ke timestamppb.timestamp
type stuff struct { //this struct non-local, this is from third-party package date *timestamppb.timestamp } stuff = stuff{} scanerr := rows.scan(&stuff.date)
Saya cuba mengimbas struktur yang melaksanakan antara muka sql.scanner. Itu mudah. Saya baru sahaja melaksanakan fungsi imbasan seperti ini:
type test struct { } func (t test) scan(src any) error { //convert value }
Tetapi ia tidak berfungsi dengan timestamppb.timestamp kerana ia adalah jenis bukan asli. Kemudian saya cuba menentukan jenis tempatan dan melakukan perkara yang sama
type timestamppb timestamppb.timestamp func (t timestamppb) scan(src any) error { //convert value }
Tetapi helah ini tidak berjaya. Selain itu, saya mempunyai amaran "'scan' pas kunci mengikut nilai: taip 'timestampb' mengandungi 'protoimpl.messagestate' mengandungi 'sync.mutex', iaitu 'sync.locker'" Ini tidak berfungsi jika saya menetapkan penunjuk untuk cap waktu
func (t *timestamppb) scan(src any) error {
Jadi saya nak tahu, macam mana nak buat timestamppb.timestamp instance sql.scanner. Adakah mungkin?
Kemas kini 1 Contoh kecil yang saya cuba
type TimestampPb timestamppb.Timestamp type test struct { //third-party struct, I can't modify it date *timestamppb.Timestamp } func (s *Storage) test() { rows, _ := s.db.Query("SELECT \"test_date\" FROM \"test_table\" LIMIT 1") defer func() { if rows != nil { _ = rows.Close() } }() for rows.Next() { //var value *TimestampPb //works //var value TimestampPb //works //var value *timestamppb.Timestamp //doesn't work //testStruct := test{} //doesn't work //err := rows.Scan(&value) //scan to variable //err := rows.Scan(&testStruct.date) //scan to field in the struct if err != nil { log.Fatalln(err) } } } func (tpb *TimestampPb) Scan(src any) error { return nil }
Saya ingin tahu sama ada saya boleh menggunakan case dengan teststruct?
pq
库不支持 *timestamppb.timestamp
sebagai jenis cap masa. Lihat dokumentasi untuk jenis tarikh yang disokong.
Jenis yang berbeza diperlukan semasa mengimbas.
Saya biasanya melakukan ini dengan menggunakan jenis pembantu dalam fungsi. Contohnya:
type row struct { Date *timestamppb.Timestamp // ... more fields here } func Query() ([]row, error) { rows, err := s.db.Query(...) if err != nil { return nil, err } defer rows.Close() var rows []row for rows.Next() { type aux struct { Date time.Time // ... more fields here } var value aux if err := rows.Scan(&value); err != nil { return nil, err } rows = append(rows, row{ Date: timestamppb.New(value.Date), // ... more fields here } } return rows, nil }
Atas ialah kandungan terperinci Bagaimana untuk menambah antara muka kepada struktur bukan asli dalam golang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!