1 回答

TA貢獻1946條經驗 獲得超3個贊
掃描器和評估器接口實際上并不是您自己使用的東西,至少在數據庫中存儲自定義類型時不是這樣。Scan()
我將首先介紹和函數的使用Value()
,然后解決您的問題。
當您獲得sql.Row
結果并想要將結果集中的值分配(掃描)到自定義類型的變量中時。文檔顯示該sql.Row.Scan()
函數接受 0 個或多個類型的參數interface{}
,基本上是任何東西。
在可以掃描值的支持類型列表中,最后一行是重要的一行:
任何實現掃描儀的類型(請參閱掃描儀文檔)
通過 function?func (ts *Timestamp) Scan(value interface{}) error {
,該Timestamp
類型現在實現了該Scanner
接口,從而允許sql.Row
向該類型分配值。該Scanner
接口的文檔位于Scan()
我上面鏈接的 文檔的正下方。
當然,這可以幫助您從數據庫讀取值,但在存儲這些類型時卻無濟于事。為此,您需要Valuer
接口。如果您還沒有猜到,該func (ts Timestamp) Value() (driver.Value, error)
函數確實使您的Timestamp
類型實現了此接口。
該Valuer
接口的要點是允許一種將任何類型轉換為 a 的方法driver.Value
,驅動程序可以使用該類型并將其存儲在數據庫中
解決問題
首先,我必須假設您的協議輸出已寫入包中v1
。如果不是,它對你來說不會有很好的效果。
有問題的行確實是您標記的行:
u.CreatedAt?=?time.Now()
首先,User.CreatedAt
類型為Timestamp
,它本身就是一條包含單個時間戳的消息。要將CreatedAt
時間設置為time.Now()
,您需要CreatedAt
正確初始化該字段:
u.CreatedAt?=?&Timestamp{ ????Timestamp:?ptypes.TimestampNow(),?//?this?returns?a?PROTOBUF?TYPE! ????}
你已經Scan
在你的函數中這樣做了Value
?,所以我真的不明白你為什么不在這里這樣做......
建議
如果協議輸出確實寫入了v1
包,我真的真的會刪除該User.Create()
函數。事實上,我會直接殺死它。您的協議緩沖區用于通信。通過 RPC 公開您的程序。這是一個 API。這些message
類型本質上是請求和響應對象(如果您愿意的話,可以美化 DTO)。您正在Create
向其中添加此功能,這會將它們變成 AR 類型。它使您的 protobuf 包無法使用。gRPC 的美妙之處在于您可以生成 golang、C++、Python...代碼,其他人可以使用這些代碼來調用您的程序。如果你讓你的 gRPC 包依賴于數據庫,就像你所做的那樣,我個人永遠不會使用它。
- 1 回答
- 0 關注
- 127 瀏覽
添加回答
舉報