面试题答案
一键面试实现思路
- 使用
reflect.ValueOf
获取传入接口值的reflect.Value
。 - 使用
reflect.TypeOf
获取传入接口值的reflect.Type
。 - 检查
reflect.Value
是否是结构体类型,如果不是则返回错误。 - 遍历结构体的字段,通过
reflect.Type.Field
获取每个字段的信息,包括标签。 - 根据标签判断对字段进行何种处理,例如加密或日志记录。
- 对于需要修改的字段值,通过
reflect.Value
的方法进行操作。
代码实现
package main
import (
"fmt"
"reflect"
)
// 模拟加密函数
func encrypt(str string) string {
return "encrypted_" + str
}
// 模拟日志记录函数
func logInfo(str string) {
fmt.Printf("Logging: %s\n", str)
}
func processStruct(data interface{}) error {
valueOf := reflect.ValueOf(data)
typeOf := reflect.TypeOf(data)
// 检查是否为指针类型,如果是则获取指针指向的值
if valueOf.Kind() == reflect.Ptr {
valueOf = valueOf.Elem()
typeOf = typeOf.Elem()
}
// 检查是否为结构体类型
if typeOf.Kind() != reflect.Struct {
return fmt.Errorf("input is not a struct")
}
for i := 0; i < typeOf.NumField(); i++ {
field := typeOf.Field(i)
tag := field.Tag.Get("process")
switch tag {
case "encrypt":
if valueOf.Field(i).Kind() == reflect.String {
original := valueOf.Field(i).String()
encrypted := encrypt(original)
valueOf.Field(i).SetString(encrypted)
}
case "log":
if valueOf.Field(i).Kind() == reflect.String {
logInfo(valueOf.Field(i).String())
}
}
}
return nil
}
你可以这样调用这个函数:
type TestStruct struct {
Name string `process:"encrypt"`
Info string `process:"log"`
}
func main() {
test := TestStruct{
Name: "John",
Info: "Some information",
}
err := processStruct(&test)
if err != nil {
fmt.Println(err)
}
fmt.Println(test)
}