Maison > Article > développement back-end > Comment ajouter une interface à une structure non native dans Golang ?
J'utilise https://github.com/lib/pq pour obtenir des données de postgres. Pour extraire les données, j'utilise une structure tierce qui contient le champ d'horodatage protobuf https://pkg.go.dev/google.golang.org/protobuf/types/known/timestampb#timestamp donc Le problème est donc de faire en sorte que le travail soit analysé de time.time à timestampb.timestamp
type stuff struct { //this struct non-local, this is from third-party package date *timestamppb.timestamp } stuff = stuff{} scanerr := rows.scan(&stuff.date)
J'essaie de scanner la structure implémentant l'interface sql.scanner. C'est simple. Je viens d'implémenter la fonction scan comme ceci :
type test struct { } func (t test) scan(src any) error { //convert value }
Mais cela ne fonctionne pas avec timestamppb.timestamp car c'est un type non natif. Ensuite, j'ai essayé de définir un type local et de faire de même
type timestamppb timestamppb.timestamp func (t timestamppb) scan(src any) error { //convert value }
Mais cette astuce n’a pas fonctionné. De plus, j'ai l'avertissement "'scan' passe le verrouillage par valeur : type 'timestamppb' contient 'protoimpl.messagestate' contient 'sync.mutex', c'est-à-dire 'sync.locker'" Cela ne fonctionne pas si je spécifie un pointeur pour timestampb
func (t *timestamppb) scan(src any) error {
Je veux donc savoir comment créer une instance timestamppb.timestamp de sql.scanner. Est-il possible?
Mise à jour 1 Petit exemple de ce que j'ai essayé
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 }
Je veux savoir si je peux utiliser case avec teststruct ?
pq
库不支持 *timestamppb.timestamp
comme type d'horodatage. Voir la documentation pour les types de dates pris en charge.
Différents types sont requis lors de la numérisation.
Je fais généralement cela en utilisant des types d'assistance dans les fonctions. Par exemple :
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 }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!