英文:
A generic golang decorator (clarification needed for a gist)
问题
有人能解释一下这个代码片段中发生了什么吗?我理解装饰器的概念以及这个实现如何让我们创建一个通用的装饰器,但是在一些部分我有点迷失(内联注释)。如果有人能为我解析一下,我会非常感激。
另外,如果这不是编写通用装饰器的最佳方式,那么什么是最佳方式呢?我正在寻找一个能够装饰类型为func(args...interface{}) (interface{}, error)
的函数的装饰器,而且不会丢失类型安全性。
以下是要翻译的代码:
package main
import (
"fmt"
"reflect"
)
func Decorate(impl interface{}) interface{} {
fn := reflect.ValueOf(impl)
// inner函数是做什么的?这段代码块是什么意思?
inner := func(in []reflect.Value) []reflect.Value { // 为什么返回值类型与传递给函数的参数类型相同?这是否意味着这个装饰器只适用于具有签名为func (arg TypeA) TypeA而不是func (arg TypeA) TypeB的函数?
f := reflect.ValueOf(impl)
fmt.Println("Stuff before")
// ...
ret := f.Call(in) // call函数是做什么的?为什么我们不能只使用f(in)?
fmt.Println("Stuff after")
// ...
return ret
}
v := reflect.MakeFunc(fn.Type(), inner)
return v.Interface()
}
var Add = Decorate(
func (a, b int) int {
return a + b
},
).(func(a, b int) int) // 这是一个类型断言吗?
func main() {
fmt.Println(Add(1, 2))
}
希望能对你有所帮助!
英文:
Can someone explain what is happening in this gist ? I understand the concept of decorators and how this implementation lets one create a generic decorator, but I am little lost in a few sections (commented inline). Would really appreciate if someone could break it down for me.
Also if this isnt the best way to write a generic decorator, what is ? I am looking for a decorator that can decorate a function of type func(args...interface{}) (interface{},error) without throwing away type safety.
https://gist.github.com/saelo/4190b75724adc06b1c5a
package main
import (
"fmt"
"reflect"
)
func Decorate(impl interface{}) interface{} {
fn := reflect.ValueOf(impl)
//What does inner do ? What is this codeblock ?
inner := func(in []reflect.Value) []reflect.Value { //Why does this return the same type as the parameters passed to the function ? Does this mean this decorator only works for fns with signature func (arg TypeA) TypeA and not func (arg TypeA) TypeB ?
f := reflect.ValueOf(impl)
fmt.Println("Stuff before")
// ...
ret := f.Call(in) //What does call do ? Why cant we just use f(in) ?
fmt.Println("Stuff after")
// ...
return ret
}
v := reflect.MakeFunc(fn.Type(), inner)
return v.Interface()
}
var Add = Decorate(
func (a, b int) int {
return a + b
},
).(func(a, b int) int) //Is this a type assertion ?
func main() {
fmt.Println(Add(1, 2))
}
答案1
得分: 1
变量inner
使用短变量声明进行声明。变量inner
的类型是func(in []reflect.Value) []reflect.Value
。该值是代码中的函数字面量。
类型func(in []reflect.Value) []reflect.Value
表示通过反射实现的通用函数。该函数接受一个可能为空的参数切片,并返回一个可能为空的结果切片。
函数的reflect.Value
不能直接调用。使用Call
方法来调用该值中的函数。
.(func(a, b int) int)
是类型断言。
英文:
The variable inner
is declared using a short variable declaration. The variable inner
has type func(in []reflect.Value) []reflect.Value
. The value is the function literal in the code.
The type func(in []reflect.Value) []reflect.Value
represents a generic function implemented by reflection. The function takes a possibly empty slice of arguments and returns a possibly empty slice of results.
The reflect.Value
for a function is not directly callable. The Call
method is used to call the function in the value.
The .(func(a, b int) int)
is a type assertion.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论