面试题答案
一键面试package main
import (
"fmt"
"reflect"
)
type B struct {
Field1 string
Field2 int
Field3 []float64
}
type A struct {
InnerB B
Field4 bool
Field5 []string
}
func printStructFields(i interface{}) {
value := reflect.ValueOf(i)
if value.Kind() == reflect.Ptr {
value = value.Elem()
}
if value.Kind() != reflect.Struct {
fmt.Println("Input is not a struct")
return
}
printFieldsRecursive(value, "")
}
func printFieldsRecursive(value reflect.Value, prefix string) {
for i := 0; i < value.NumField(); i++ {
field := value.Field(i)
fieldName := prefix + value.Type().Field(i).Name
switch field.Kind() {
case reflect.Struct:
printFieldsRecursive(field, fieldName+".")
case reflect.Slice:
fmt.Printf("%s: []\n", fieldName)
for j := 0; j < field.Len(); j++ {
item := field.Index(j)
if item.Kind() == reflect.Struct {
printFieldsRecursive(item, fieldName+"["+fmt.Sprintf("%d", j)+"].")
} else {
fmt.Printf("%s[%d]: %v\n", fieldName, j, item.Interface())
}
}
default:
fmt.Printf("%s: %v\n", fieldName, field.Interface())
}
}
}
func main() {
a := A{
InnerB: B{
Field1: "Hello",
Field2: 42,
Field3: []float64{1.1, 2.2, 3.3},
},
Field4: true,
Field5: []string{"a", "b", "c"},
}
printStructFields(a)
}
在上述代码中:
printStructFields
函数是对外暴露的接口,它首先检查传入的参数是否为指针,如果是则取其指向的值,然后检查值是否为结构体类型。如果不是结构体类型则输出错误信息并返回。printFieldsRecursive
函数是一个递归函数,用于遍历结构体的字段。- 对于结构体字段,递归调用
printFieldsRecursive
继续遍历。 - 对于切片字段,先打印切片的开头,然后遍历切片元素。如果元素是结构体,则递归调用
printFieldsRecursive
;否则直接打印元素值。 - 对于其他类型的字段,直接打印字段名和字段值。
- 对于结构体字段,递归调用
在 main
函数中,创建了一个 A
结构体实例并调用 printStructFields
函数打印其所有字段值。