亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Go 中泛化函數包裝?

如何在 Go 中泛化函數包裝?

Go
阿晨1998 2022-06-27 16:17:39
我有以下界面:type Selector interface {    SelectOne(ctx context.Context, one A) (Result, error)    SelectTwo(ctx context.Context, one A, two B) ([]Result, error)    SelectThree(ctx context.Context, one A, two B, three C) ([]Result, error)}以及以下實現:type Database struct{}func (d Database) SelectOne(...) (...) {...}func (d Database) SelectTwo(...) (...) {...}func (d Database) SelectThree(...) (...) {...}然后,最重要的是,我想添加一個使用非常好的 github.com/hashicorp/golang-lru 庫的緩存層:type SelectorCache struct {    db        Database    cacheOne *lru.Cache    cacheTwo *lru.Cache}func (c SelectorCache) SelectOne(ctx context.Context, one A) (Result, error) {    cached, ok := c.cacheOne.Get(makeKey(one))    if ok {        casted, ok := cached.(Result)        if ok {            return casted, nil        }    }    fetched, err := c.db.SelectOne(ctx, one)    if err != nil {        return Result{}, err    }    c.cache.Add(key, fetched)    return fetched, nil}func (c SelectorCache) SelectTwo(ctx context.Context, one A, two B) ([]Result, error) {    ...        casted, ok := cached.([]Result)    ...    fetched, err := c.db.SelectTwo(ctx, one, two)    ...}func () SelectThree(ctx context.Context, one A, two B, three C) ([]Result, error) {    ...        casted, ok := cached.([]Result)    ...    fetched, err := c.db.SelectThree(ctx, one, two, three)    ...}如您所見,每種情況下的緩存層基本相同,唯一的區別在于底層功能。如果那是 Python,我可以輕松地創建一個將 *a, **kw 傳遞給被包裝函數的包裝函數。我怎樣才能重寫它以便樣板消失?
查看完整描述

2 回答

?
慕容708150

TA貢獻1831條經驗 獲得超4個贊

您可以編寫一個可變參數函數(請參閱函數類型),它將任意數量的ints 作為參數(零或更多)并一次性處理它們。例如


func (d Database) Select(ctx context.Context, numbers ...int)

numbers您可以在for 循環中迭代range并執行您想要的操作。您的函數調用可以保持與以前相同。


fetched, err := c.db.Select(ctx, one)

fetched, err := c.db.Select(ctx, one, two)

fetched, err := c.db.Select(ctx, one, two, three)


查看完整回答
反對 回復 2022-06-27
?
縹緲止盈

TA貢獻2041條經驗 獲得超4個贊

您在評論中提到參數類型有所不同。

一般來說,您可以這樣做:

  • 在編譯時,或

  • 在運行時。

運行時版本更易于編碼和使用,并且非常靈活,但當然有一些運行時成本。也許您正試圖避免這種情況(這很好,但會讓人想起關于在優化之前進行測量的古老格言)。

編譯時版本是您在示例中編寫的。

我怎樣才能重寫它以便樣板消失?

對于 Go 1,只有一種方法可以做到這一點:編寫程序來編寫程序。?? 這就是go generate全部。還有一篇關于它的Go 博客文章。

在 Go 2 中,幾乎肯定會有泛型,你實際上可以稍微玩一下。他們將是做你想做的事的方式。


查看完整回答
反對 回復 2022-06-27
  • 2 回答
  • 0 關注
  • 131 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號