我使用 https://github.com/lib/pq 從 postgres 取得資料。 為了提取數據,我使用第三方結構,其中包含 protobuf timestamp 字段 https://pkg.go.dev/google.golang.org/protobuf/types/known/timestamppb#timestamp 所以 所以問題是讓工作從 time.time 掃描到 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)
我嘗試掃描結構實作 sql.scanner 介面。那很簡單。我只是像這樣實作 scan 功能:
type test struct { } func (t test) scan(src any) error { //convert value }
但它不適用於timestamppb.timestamp,因為它是非本機類型。 然後我嘗試定義本地類型並執行相同的操作
type timestamppb timestamppb.timestamp func (t timestamppb) scan(src any) error { //convert value }
但是這個技巧並沒有奏效。此外,我有警告“‘scan’通過值傳遞鎖:類型‘timestamppb’包含‘protoimpl.messagestate’包含‘sync.mutex’,即‘sync.locker’” 如果我為 timestamppb 指定指針,這將不起作用
func (t *timestamppb) scan(src any) error {
所以我想知道,如何製作 sql.scanner 的 timestamppb.timestamp 實例。可能嗎?
更新 1 我嘗試過的小例子
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 }
我想知道我是否可以將 case 與 teststruct 一起使用?
pq
函式庫不支援 *timestamppb.timestamp
作為時間戳類型。 請參閱文件中支援的日期類型。
掃描時需要不同的類型。
我通常透過在函數中使用輔助類型來做到這一點。例如:
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 }
以上是如何在golang中為非本地結構新增介面?的詳細內容。更多資訊請關注PHP中文網其他相關文章!