用Go反射遍历任意结构体字段需传指针,通过reflect.ValueOf和reflect.TypeOf获取值与类型,递归处理结构体、切片、map等,支持标签解析与缩进打印。

用 Go 语言遍历任意结构体字段并打印,核心是 反射(reflect)。Go 不支持传统意义上的“运行时字段枚举”,但 reflect 包提供了安全、通用的方案,适用于任意嵌套结构体、指针、基础类型、切片、map 等。
必须传入结构体指针(*T),否则 reflect.Value 无法获取导出字段(首字母大写)。使用 reflect.TypeOf 和 reflect.ValueOf 获取类型和值信息,再通过 .NumField() 和 .Field(i) 遍历:
.Elem() 解引用到实际结构体值.Kind() == reflect.Struct).Type().Field(i) 获取字段名、标签;.Field(i) 获取字段值递归是关键。对每个字段值做类型判断,再决定是否深入:
通过 structField.Tag.Get("json") 或自定义 tag(如 "print")控制显示逻辑。配合层级深度参数实现缩进,提升可读性:
立即学习“go语言免费学习笔记(深入)”;
indent + " ")json 名(若存在且非 "-"), fallback 到原始字段名以下是一个轻量、健壮的打印函数(已处理空指针、循环引用简化、非导出字段跳过):
func PrintStruct(v interface{}, indent string) {
rv := reflect.ValueOf(v)
if !rv.IsValid() {
fmt.Println(indent + "(invalid)")
return
}
if rv.Kind() == reflect.Ptr {
if rv.IsNil() {
fmt.Println(indent + "<nil>")
return
}
fmt.Println(indent + "&{")
PrintStruct(rv.Elem().Interface(), indent+" ")
fmt.Println(indent + "}")
return
}
if rv.Kind() != reflect.Struct {
fmt.Printf("%s%v\n", indent, rv.Interface())
return
}
rt := reflect.TypeOf(v).Elem()
for i := 0; i < rv.NumField(); i++ {
field := rt.Field(i)
value := rv.Field(i)
if !value.CanInterface() { // 非导出字段跳过
continue
}
name := field.Name
if jsonTag := field.Tag.Get("json"); jsonTag != "" && jsonTag != "-" {
if idx := strings.Index(jsonTag, ","); idx > 0 {
name = jsonTag[:idx]
} else {
name = jsonTag
}
}
fmt.Printf("%s%s: ", indent, name)
PrintStruct(value.Interface(), indent+" ")
}
}以上就是如何使用Golang实现对象字段遍历打印_支持任意结构体的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号