You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言获取含encr标签结构体字段名,嵌套指针结构体失效问题

解决Go结构体指针嵌套字段的encr标签提取问题

你的核心问题是没递归处理嵌套的结构体指针类型,且处理指针时没处理零值指针的情况。下面是修复后的代码,能递归提取所有带encr标签的字段名到map中:

package main

import (
	"fmt"
	"reflect"
)

type Address struct {
	Street string `encr:"true"`
	City   string
}

type User struct {
	Name    string        `encr:"true"`
	Age     int
	Addr    *Address      `encr:"true"`
	Contact *ContactInfo  `encr:"true"`
}

type ContactInfo struct {
	Phone string `encr:"true"`
	Email string
}

func extractEncryptedFields(v interface{}, fieldMap map[string]bool) {
	val := reflect.ValueOf(v)
	// 处理指针类型,先取Elem
	if val.Kind() == reflect.Ptr {
		// 如果指针是零值,创建对应类型的零值实例避免空指针panic
		if val.IsNil() {
			val = reflect.New(val.Type().Elem())
		}
		val = val.Elem()
	}
	// 非结构体类型直接返回
	if val.Kind() != reflect.Struct {
		return
	}

	typ := val.Type()
	for i := 0; i < val.NumField(); i++ {
		field := typ.Field(i)
		// 检查当前字段是否有encr标签
		if tag := field.Tag.Get("encr"); tag == "true" {
			fieldMap[field.Name] = true
		}

		// 递归处理嵌套字段,覆盖结构体和结构体指针
		fieldVal := val.Field(i)
		extractEncryptedFields(fieldVal.Interface(), fieldMap)
	}
}

func main() {
	user := User{
		Name: "Alice",
		Age:  30,
		Addr: &Address{
			Street: "Main St",
			City:   "NYC",
		},
		Contact: &ContactInfo{
			Phone: "1234567890",
		},
	}

	fieldMap := make(map[string]bool)
	extractEncryptedFields(user, fieldMap)

	fmt.Println("Encrypted fields:", fieldMap)
}

关键修复点:

  1. 递归遍历嵌套类型:不管字段是结构体还是结构体指针,都递归调用提取函数,确保嵌套层级的标签被捕获。
  2. 零值指针安全处理:遇到nil指针时,自动创建对应类型的零值实例,避免调用Elem()触发panic。
  3. 指针类型解析逻辑:先判断字段是否为指针类型,解析出底层结构体后再执行后续的字段遍历逻辑。

运行代码后,会正确输出所有带encr:"true"的字段:Name、Addr、Street、Contact、Phone。

内容的提问来源于stack exchange,提问作者Muhammed Jishin Jamal TCP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:45:11