英文:
Declare a function parameter with returning value error
问题
我正在编写一个可以包装任何方法的指标方法。类似于:
func DoAndMonitor(f func() error, simpleKey string) {
metrics.IncrCounter("activity."+simpleKey+".cnt", 1)
if err := f(); err != nil {
metrics.IncrCounter("activity."+simpleKey+".fail", 1)
} else {
metrics.IncrCounter("activity."+simpleKey+".fail", 1)
}
}
这对某些情况有效。但是使用起来并不容易,比如我有以下任意函数:
myMethod() (val1 string , val2 string , err error)
myMethod2() (val string , err error)
myMethod3() (err error)
myMethod4() (val int64, err error)
当我使用myMethod()
时,可能会写出类似以下的代码:
ret1, ret2, err := myMethod()
if err := nil {
//log
return nil, err;
} else {
//do something...
return something, nil
}
但是当我使用DoAndMonitor
时,我希望DoAndMonitor
函数能够返回与myMethod
相同的类型,例如:
ret1, ret2, err := DoAndMonitor(func(){
return myMethod()
},"mykey");// 这是我希望的,但现在我无法实现
if err := nil {
//log
return nil, err;
} else {
//do something...
return something, nil
}
我该如何实现这个目标?
英文:
I am writing a method to do metrics that can wrap any method. Something like:
func DoAndMonitor(f func() error, simpleKey string) {
metrics.IncrCounter("activity."+simpleKey+".cnt", 1)
if err := f(); err != nil {
metrics.IncrCounter("activity."+simpleKey+".fail", 1)
} else {
metrics.IncrCounter("activity."+simpleKey+".fail", 1)
}
}
This works for some cases. But it is not easy to use, say I have any functions below,
myMethod() (val1 string , val2 string , err error)
myMethod()2 (val string , err error)
myMethod()3 ( err error)
myMethod()4 (val int64, err error)
When I use myMethod()
, I may write something like:
ret1, ret2, err := myMethod()
if err :=nil {
//log
return nil, err;
} else {
//do something...
return something,nil
}
But when I use DoAndMonitor
, I hope the DoAndMonitor
function can return the same type as myMethod
like :
ret1, ret2, err := DoAndMonitor(func(){
return myMethod()
},"mykey");// this is what i hope, but i can't do this now
if err :=nil {
//log
return nil, err;
} else {
//do something...
return something,nil
}
How can I achieve this?
答案1
得分: 1
你可以通过使用类型参数并对同一个函数进行几个变体来实现最接近的效果。
func DoAndMonitor(f func() error, simpleKey string) { ... }
func DoAndMonitor1[T any](f func() (T, error), simpleKey string) T {
x, err := f()
if err != nil {
metrics.IncrCounter("activity."+simpleKey+".fail", 1)
} else {
metrics.IncrCounter("activity."+simpleKey+".success", 1)
}
return x
}
// 其他变体...
然后你可以这样调用你的函数:
x := DoAndMonitor1[int](func() (int, error) { return 42, nil }, "foo")
这是一个快速的 Playground 链接,用于演示这个概念,但是使用 panic 替代了你的指标统计:https://go.dev/play/p/SMAhUCoIYcj
英文:
The closest you can get to this is by using type parameters and making a few variations of the same function.
func DoAndMonitor(f func() error, simpleKey string) { ... }
func DoAndMonitor1[T any](f func() (T, error), simpleKey string) T {
x, err := f()
if err != nil {
metrics.IncrCounter("activity."+simpleKey+".fail", 1)
} else {
metrics.IncrCounter("activity."+simpleKey+".success", 1)
}
return x
}
// and so on...
You could then invoke your function like so:
x := DoAndMonitor1[int](func() (int, error) { return 42, nil }, "foo")
A quick playground link to demonstrate this, but with panics instead of your nice metrics.
https://go.dev/play/p/SMAhUCoIYcj
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论