function - 如何在Go中概括函数包装?

标签 function go

我有以下界面:

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传递给包装函数的包装函数。我该如何重写,以使样板消失?

最佳答案

您在注释中提到参数类型有所不同。
通常,您可以执行以下操作:

编译时为

  • 在运行时。

  • 运行时版本更易于编码和使用,并且非常灵活,但是当然会花费一些运行时成本。也许您正在尝试避免这种情况(很好,但是请记住关于在优化之前进行测量的古老说法)。
    编译时版本就是您在示例中编写的版本。

    How can I rewrite that so the boilerplate gets gone?


    对于Go 1,只有一种方法可以做到:编写程序来编写程序。 oji这就是 go generate 的全部含义。也有一个Go blog post
    在Go 2中,几乎可以肯定会有generics,您实际上可以稍微玩一下。它们将成为您想要做的方式。

    关于function - 如何在Go中概括函数包装?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63776909/

    相关文章:

    javascript - 此函数如何从数组中删除所有虚假值?

    java - 如何使用 Luaj 向 _G 添加运行 java 代码的函数?

    go - 同一项目的不同文件夹中的相同包名称

    go - 如何理解这个例子中的 goroutines 执行?

    java - 静态和非静态访问值

    php - 设置对 PHP 函数的调用,将 POST 变量作为参数,作为 HTML 表单操作

    http - 使用 http.ServeFile 更改 HTTP 代码

    json - 在 golang 中检查 JSON 字符串是否有效

    go - 将多返回函数的结果传递给另一个在 Go 中只接受一个参数的结果

    python - 将函数内部的变量传递给函数外部的变量