【问题标题】:How to create a new function from another function using reflection如何使用反射从另一个函数创建新函数
【发布时间】:2020-04-02 21:35:53
【问题描述】:

将此代码用作模板

package main

import "fmt"

type myStruct struct {
    Value int
}

type counter int

func newFuncHandler(fn func(myStruct) error) (interface{}, *counter) {
    count := counter(0)

    newFn := func(e myStruct) error {
        count = count + 1
        return fn(e)
    }

    return newFn, &count
}

func main() {
    fn := func(d myStruct) error {
        // doing some stuff
        return nil
    }

    handle, c := newFuncHandler(fn)
    handleFn := handle.(func(d myStruct) error)

    handleFn(myStruct{Value: 2})
    handleFn(myStruct{Value: 2})
    handleFn(myStruct{Value: 2})
    handleFn(myStruct{Value: 2})
    handleFn(myStruct{Value: 2})

    fmt.Println(*c) // 5
}

如何修改newFuncHandler,使其在给定签名未知的函数的情况下返回一个具有相同签名但函数体有附加代码的函数。 newFuncHandler 不应该知道 myStruct 类型

例如

func newFuncHandler(fn interface{}) (interface{}, *counter) {
    count := counter(0)
    // some reflection magic

    // newFn has the same signature as fn (hardcoded in this case)
    newFn := func(e myStruct) error {
        // add custom code 
        count = count + 1

        // call the original fn
        return fn(e)
    }

    return newFn, &count
}

【问题讨论】:

    标签: go go-reflect


    【解决方案1】:

    使用reflect.MakeFunc 来创建一个函数。使用Value.Call 调用函数。

    func newFuncHandler(v interface{}) (interface{}, *counter) {
        count := counter(0)
        fn := reflect.ValueOf(v)
        newFn := reflect.MakeFunc(fn.Type(), func(args []reflect.Value) (results []reflect.Value) {
            count = count + 1
            return fn.Call(args)
        })
        return newFn.Interface(), &count
    }
    

    Run it on the playground.

    【讨论】:

    • 用户名说明了一切!
    猜你喜欢
    • 1970-01-01
    • 2012-03-30
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多