From 5a898f58dc37027b3ba1b5deac6f573bb8d3c52f Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Wed, 27 Dec 2023 10:57:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20reflects=20=E5=8C=85=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20FuncWrapper=20=E7=9B=B8=E5=85=B3=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/reflects/func.go | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 utils/reflects/func.go diff --git a/utils/reflects/func.go b/utils/reflects/func.go new file mode 100644 index 0000000..c30fc2d --- /dev/null +++ b/utils/reflects/func.go @@ -0,0 +1,48 @@ +package reflects + +import ( + "fmt" + "reflect" +) + +// WrapperFunc 包装函数 +func WrapperFunc[Func any](f any, wrapper func(call func([]reflect.Value) []reflect.Value) func(args []reflect.Value) []reflect.Value) (wf Func, err error) { + tof := reflect.TypeOf(f) + if tof.Kind() != reflect.Func { + return wf, fmt.Errorf("f is not a function, got %v", tof.String()) + } + return reflect.MakeFunc(tof, wrapper(func(args []reflect.Value) []reflect.Value { + return reflect.ValueOf(f).Call(args) + })).Interface().(Func), nil +} + +// WrapperFuncBefore2After 包装函数,前置函数执行前,后置函数执行后 +func WrapperFuncBefore2After[Func any](f Func, before, after func()) (wf Func, err error) { + vof := reflect.ValueOf(f) + tof := vof.Type() + if tof.Kind() != reflect.Func { + return wf, fmt.Errorf("f is not a function, got %v", tof.String()) + } + wrapped := reflect.MakeFunc(tof, func(args []reflect.Value) []reflect.Value { + if before != nil { + before() + } + result := vof.Call(args) + if after != nil { + after() + } + return result + }) + + return wrapped.Interface().(Func), nil +} + +// WrapperFuncBefore 包装函数,前置函数执行前 +func WrapperFuncBefore[Func any](f Func, before func()) (wf Func, err error) { + return WrapperFuncBefore2After(f, before, nil) +} + +// WrapperFuncAfter 包装函数,后置函数执行后 +func WrapperFuncAfter[Func any](f Func, after func()) (wf Func, err error) { + return WrapperFuncBefore2After(f, nil, after) +}