面试题答案
一键面试package main
import (
"fmt"
"reflect"
)
func CallFunction(f interface{}, args ...interface{}) (results []interface{}, err error) {
// 获取函数的反射值
funcValue := reflect.ValueOf(f)
if funcValue.Kind() != reflect.Func {
return nil, fmt.Errorf("input is not a function")
}
// 检查参数数量
if len(args) != funcValue.Type().NumIn() {
return nil, fmt.Errorf("number of arguments does not match")
}
// 准备参数的反射值
var argValues []reflect.Value
for i, arg := range args {
argValue := reflect.ValueOf(arg)
if argValue.Type() != funcValue.Type().In(i) {
return nil, fmt.Errorf("argument %d type does not match", i)
}
argValues = append(argValues, argValue)
}
// 调用函数
resultsValues := funcValue.Call(argValues)
// 处理返回值
for _, resultValue := range resultsValues {
results = append(results, resultValue.Interface())
}
return results, nil
}
// 示例函数1:接受两个整数并返回它们的和
func Add(a, b int) int {
return a + b
}
// 示例函数2:接受一个字符串并返回其长度
func StringLength(s string) int {
return len(s)
}
func main() {
// 调用Add函数
result, err := CallFunction(Add, 3, 5)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Add result:", result[0])
}
// 调用StringLength函数
result, err = CallFunction(StringLength, "hello")
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("StringLength result:", result[0])
}
}
上述代码中:
CallFunction
函数接受一个接口类型的函数f
以及可变数量的接口类型参数args
。- 使用
reflect.ValueOf
获取函数的反射值,并检查其是否为函数类型。 - 检查传入的参数数量是否与函数期望的参数数量一致。
- 遍历传入的参数,检查每个参数的类型是否与函数期望的参数类型一致。
- 使用
funcValue.Call
调用函数,并获取返回值。 - 将返回值的反射值转换为接口类型,并添加到结果切片中。
- 在
main
函数中,通过CallFunction
调用了两个不同的示例函数Add
和StringLength
,展示了如何动态调用不同参数和返回值类型的函数,并处理可能的错误。