doubiao9775
doubiao9775
2017-07-30 02:40

通用golang装饰器(要点说明)

  • decorator
已采纳

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条回答

  • duanbeng8872 duanbeng8872 4年前

    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.

    点赞 评论 复制链接分享

为你推荐