如何动态反射(reflect)创建新的参数并调用函数?

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

how to dynamic reflect.New params and call the func?

问题

我想在接收HTTP调用时使用普通函数而不是HttpHandler,所以我应该动态地使用新参数调用该函数。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	invoke(test)
}

func invoke(function interface{}) {
	funcType := reflect.TypeOf(function)
	if funcType.Kind() == reflect.Func {
		paramType := funcType.In(0).Elem()
		input := reflect.New(paramType)
		input.Elem().Field(0).SetString("neason")
		input.Elem().Field(1).SetInt(18)

		fmt.Println(input)

		funcValue := reflect.ValueOf(function)

		params := []reflect.Value{
			input.Elem(),
		}

		funcValue.Call(params)
	}
}

type Input struct {
	Name string
	Age  int
}

type Output struct {
	Name string
	Age  int
}

func test(input *Input) Output {
	return Output{
		Name: input.Name,
		Age:  input.Age,
	}
}

它会出现 panic: reflect: Call using *reflect.Value as type *main.Input 的错误。如何动态地使用 reflect.New 创建参数并调用该函数呢?

英文:

i want to use a normal func instead of a HttpHandler when receiving a http call
so i should dynamic new params to call the func.

package main

import (
	"fmt"
	"reflect"
)

func main() {
	invoke(test)
}

func invoke(function interface{}) {
	funcType := reflect.TypeOf(function)
	if funcType.Kind() == reflect.Func {
		paramType := funcType.In(0).Elem()
		input := reflect.New(paramType)
		input.Elem().Field(0).SetString("neason")
		input.Elem().Field(1).SetInt(18)

		fmt.Println(input)

		funcValue := reflect.ValueOf(function)

		params := []reflect.Value{
			reflect.ValueOf(input),
		}

		funcValue.Call(params)
	}
}

type Input struct {
	Name string
	Age  int
}

type Output struct {
	Name string
	Age  int
}

func test(input *Input) Output {
	return Output{
		Name: input.Name,
		Age:  input.Age,
	}
}

it will panic: reflect: Call using *reflect.Value as type *main.Input
how to dynamic reflect.New params and call the func ?

答案1

得分: 2

你有一个额外的reflect.Value包装层。直接使用input作为参数。它已经是一个reflect.Value

params := []reflect.Value{input}

https://go.dev/play/p/dpIspUFfbu0

英文:

You have an extra layer of reflect.Value wrappers. Use input directly as the parameter. It's already a reflect.Value.

	params := []reflect.Value{input}

https://go.dev/play/p/dpIspUFfbu0

huangapple
  • 本文由 发表于 2022年1月6日 12:33:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/70602510.html
匿名

发表评论

匿名网友

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

确定