首頁 > 後端開發 > Golang > 主體

如何在golang中為非本地結構新增介面?

王林
發布: 2024-02-06 08:18:11
轉載
1084 人瀏覽過

如何在golang中為非本地結構新增介面?

問題內容

我使用 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中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板