面试题答案
一键面试- 确保参数类型匹配:
- 在Go中使用反射调用结构体方法时,在传递参数之前,先检查参数类型是否匹配。可以通过
reflect.TypeOf
获取参数的类型,然后与方法定义的参数类型进行比较。 - 以下是示例代码:
- 在Go中使用反射调用结构体方法时,在传递参数之前,先检查参数类型是否匹配。可以通过
package main
import (
"fmt"
"reflect"
)
type Person struct {
Age int
}
func (p *Person) SetAge(age int) {
p.Age = age
}
func main() {
p := &Person{}
valueOf := reflect.ValueOf(p)
method := valueOf.MethodByName("SetAge")
if method.IsValid() {
arg := 25
argType := reflect.TypeOf(arg)
methodType := method.Type()
if methodType.NumIn() == 1 && methodType.In(0).Kind() == argType.Kind() {
method.Call([]reflect.Value{reflect.ValueOf(arg)})
} else {
fmt.Println("参数类型不匹配")
}
} else {
fmt.Println("方法不存在")
}
}
- 不匹配时优雅处理并返回合适错误信息:
- 可以自定义错误类型,然后在参数类型不匹配时返回该错误。
- 示例如下:
package main
import (
"errors"
"fmt"
"reflect"
)
type Person struct {
Age int
}
func (p *Person) SetAge(age int) {
p.Age = age
}
var ErrInvalidArgType = errors.New("参数类型无效")
func callMethodWithReflection(p interface{}, methodName string, args...interface{}) error {
valueOf := reflect.ValueOf(p)
method := valueOf.MethodByName(methodName)
if!method.IsValid() {
return fmt.Errorf("方法 %s 不存在", methodName)
}
if len(args) != method.Type().NumIn() {
return fmt.Errorf("参数数量不匹配,期望 %d 个参数,实际传入 %d 个", method.Type().NumIn(), len(args))
}
var values []reflect.Value
for i, arg := range args {
argType := reflect.TypeOf(arg)
methodInType := method.Type().In(i)
if argType.Kind() != methodInType.Kind() {
return ErrInvalidArgType
}
values = append(values, reflect.ValueOf(arg))
}
method.Call(values)
return nil
}
func main() {
p := &Person{}
err := callMethodWithReflection(p, "SetAge", 25)
if err != nil {
fmt.Println(err)
}
err = callMethodWithReflection(p, "SetAge", "twenty - five")
if err != nil {
fmt.Println(err)
}
}
在上述代码中,callMethodWithReflection
函数封装了反射调用方法的逻辑,在参数类型不匹配时返回ErrInvalidArgType
错误,并且对方法不存在和参数数量不匹配也进行了错误处理。