gpt4 book ai didi

go - Go中任意函数的包装器

转载 作者:IT王子 更新时间:2023-10-29 01:27:16 24 4
gpt4 key购买 nike

是否可以为 Go 中的任意函数创建一个包装器,使其接受相同的参数并返回相同的值?

我不是在谈论看起来完全一样的包装器,它可能看起来不同,但它应该可以解决问题。

例如,问题可能是创建一个任意函数的包装器,它首先在缓存中查找函数调用的结果,只有在缓存未命中的情况下才执行包装的函数。

最佳答案

这是一个使用 reflect.MakeFunc 的解决方案.这个特定的解决方案假定您的转换函数知道如何处理每种不同类型的函数。观看此操作:http://play.golang.org/p/7ZM4Hlcqjr

package main

import (
"fmt"
"reflect"
)

type genericFunction func(args []reflect.Value) (results []reflect.Value)

// A transformation takes a function f,
// and returns a genericFunction which should do whatever
// (ie, cache, call f directly, etc)
type transformation func(f interface{}) genericFunction

// Given a transformation, makeTransformation returns
// a function which you can apply directly to your target
// function, and it will return the transformed function
// (although in interface form, so you'll have to make
// a type assertion).
func makeTransformation(t transformation) func(interface{}) interface{} {
return func(f interface{}) interface{} {
// g is the genericFunction that transformation
// produced. It will work fine, except that it
// takes reflect.Value arguments and returns
// reflect.Value return values, which is cumbersome.
// Thus, we do some reflection magic to turn it
// into a fully-fledged function with the proper
// type signature.
g := t(f)

// typ is the type of f, and so it will also
// be the type that of the function that we
// create from the transformation (that is,
// it's essentially also the type of g, except
// that g technically takes reflect.Value
// arguments, so we need to do the magic described
// in the comment above).
typ := reflect.TypeOf(f)

// v now represents the actual function we want,
// except that it's stored in a reflect.Value,
// so we need to get it out as an interface value.
v := reflect.MakeFunc(typ, g)
return v.Interface()
}
}

func main() {
mult := func(i int) int { return i * 2 }

timesTwo := func(f interface{}) genericFunction {
return func(args []reflect.Value) (results []reflect.Value) {
// We know we'll be getting an int as the only argument,
// so this type assertion will always succeed.
arg := args[0].Interface().(int)

ff := f.(func(int) int)

result := ff(arg * 2)
return []reflect.Value{reflect.ValueOf(result)}
}
}

trans := makeTransformation(timesTwo)

// Since mult multiplies its argument by 2,
// and timesTwo transforms functions to multiply
// their arguments by 2, f will multiply its
// arguments by 4.
f := trans(mult).(func(int) int)

fmt.Println(f(1))
}

关于go - Go中任意函数的包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23166411/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com