一个通用的golang装饰器(需要对一个代码片段进行澄清)

huangapple go评论105阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2017年7月30日 10:40:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/45395861.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定