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

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

王林
Lepaskan: 2024-02-06 08:18:11
ke hadapan
1114 orang telah melayarinya

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)
Salin selepas log masuk

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
}
Salin selepas log masuk

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
}
Salin selepas log masuk

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 {
Salin selepas log masuk

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
}
Salin selepas log masuk

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
}
Salin selepas log masuk

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!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan