Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menambah antara muka kepada struktur bukan asli dalam golang?

Bagaimana untuk menambah antara muka kepada struktur bukan asli dalam golang?

王林
王林ke hadapan
2024-02-06 08:18:111034semak imbas

Bagaimana untuk menambah antara muka kepada struktur bukan asli dalam golang?

Kandungan soalan

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?


Jawapan betul


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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam