Sunday, January 5, 2014

go 的反射以及injection 设计

函数拦截设计
func Inject(fptr,target interface{},before,after func([]reflect.Value)[]reflect.Value){
        wrap := func(in []reflect.Value) []reflect.Value{
                var b []reflect.Value
                if before == nil {
                        b = in
                } else {
                        b = before(in)
                }
                v := reflect.ValueOf(target)
                r := v.Call(b)
                if after == nil {
                        return r
                } else {
                        return after(r)
                }
        }
        fn := reflect.ValueOf(fptr).Elem()
        v := reflect.MakeFunc(fn.Type(),wrap)
        fn.Set(v)
}
使用实例:
func say(word string)string{
        fmt.Println(word)
        return word
}
func main(){
        var impl func(string)string
        m :=xx{}

        Inject(&impl,say,
                func(in []reflect.Value)[]reflect.Value{
                        fmt.Println("before")
                        return in
                },
                func(out []reflect.Value)[]reflect.Value{
                        fmt.Println("after")
                        vo := "new"
                        return []reflect.Value{reflect.ValueOf(vo)}
                })
        s:=impl("old")
}
运行结果:
before
old
after
new

No comments:

Post a Comment