类似于 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 个有大量的复制和粘贴。我想改进这段代码,我的想法是创建一些我将在任何地方调用的通用方法。
应该
- 致电
CommonMethod1()
- 致电
CommonMethod2()
- 调用我在参数中传递给它的一些方法
- 出错时调用
CommonMethod3()
- return 参数
你能告诉我在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()
}
}
我在 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 个有大量的复制和粘贴。我想改进这段代码,我的想法是创建一些我将在任何地方调用的通用方法。
应该
- 致电
CommonMethod1()
- 致电
CommonMethod2()
- 调用我在参数中传递给它的一些方法
- 出错时调用
CommonMethod3()
- return 参数
你能告诉我在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()
}
}