类似于 Go 中的 lambda 表达式(合并相似的方法)

Something like lambda expressions in Go (merge similar methods)

我在 Go 中有一个结构,它有十多个方法。而且他们几乎都是一样的。其实只是一行的区别

让我们看一下简化的例子。这是第一种方法:

func (s *service) GetUser(i int, s string) (*SomeObject, error) {
    CommonMethod1()
    CommonMethod2()

    user, err := s.internalLayer.GetUser(i, s)

    if err != nil {
        CommonMethod3()
    }
    return user, err
}

第二个:

func (s *service) CheckUser(i int) (bool, error) {
    CommonMethod1()
    CommonMethod2()

    exists, err := s.internalLayer.CheckUser(i)

    if err != nil {
        CommonMethod3()
    }
    return exists, err
}

另外还有将近 10 个有大量的复制和粘贴。我想改进这段代码,我的想法是创建一些我将在任何地方调用的通用方法。

应该

你能告诉我在Go中是否可以实现这样的通用方法?

user, err := s.GetUser(i, s)
exists, err := s.CheckUser(i)

具有不同的参数计数和不同的 return 类型。

您可以使用闭包 DRY 它:

func GetUser2(i int, s string) (*User, error) {
    var u *User
    err := do(func() error {
        var err error
        u, err = getUser(i, s)
        return err
    })
    return u, err
}

func CheckUser2(i int) (bool, error) {
    var b bool
    err := do(func() error {
        var err error
        b, err = checkUser(i)
        return err
    })
    return b, err
}

func do(f func() error) error {
    CommonMethod1()
    CommonMethod2()

    err := f()
    if err != nil {
        CommonMethod3()
    }
    return err
}

如果CommonMethod1()CommonMethod2()的调用不必先于内部层的调用,基本上可以合并到一个检查函数中,甚至不需要闭包或函数值(也不需要 return 来自 check() 的传递错误):

func (s *service) GetUser(i int, s string) (*SomeObject, error) {
    user, err := s.internalLayer.GetUser(i, s)
    check(err)
    return user, err
}

func (s *service) CheckUser(i int) (bool, error) {
    exists, err := s.internalLayer.CheckUser(i)
    check(err)
    return exists, err
}

func check(err error) {
    CommonMethod1()
    CommonMethod2()
    if err != nil {
        CommonMethod3()
    }
}

如果CommonMethod1()CommonMethod2()的调用必须先于对内层的调用,那么你可以使用闭包,但是使用named result parameters简化了代码,同样,没有必要return 常用函数的错误:

func (s *service) GetUser(i int, s string) (user *SomeObject, err error) {
    do(func() error {
        user, err = s.internalLayer.GetUser(i, s)
        return err
    })
    return
}

func (s *service) CheckUser(i int) (exists bool, err error) {
    do(func() error {
        exists, err = s.internalLayer.CheckUser(i)
        return err
    })
    return
}

func do(f func() error) {
    CommonMethod1()
    CommonMethod2()

    if err := f(); err != nil {
        CommonMethod3()
    }
}