struct标签本质是供反射读取的字符串,编译器忽略其内容;json:"name"生效因encoding/json主动解析,filtered:"true"无效因无库调用Tag.Get("filtered");标签格式错误(如逗号分隔、缺双引号)会导致Get()返回空字符串且不报错。

struct 标签不是语法糖,也不是编译期特性——它只是反射能读到的一段字符串。你写得再漂亮,reflect 不去读,它就等于没写;库不按约定解析,它就只是注释。
为什么 json:"name" 能生效,而 filtered:"true" 没反应?
因为 encoding/json 包在 json.Marshal() 时主动调用 field.Tag.Get("json"),并按规则解析;但没人调用 field.Tag.Get("filtered"),这个标签就永远躺在内存里睡大觉。
-
json:、db:、xml:这些键名本身无意义,全靠对应库约定俗成地读取 - 自定义标签(如
validate:、swagger:)必须搭配相应中间件或工具链才起作用 - 写错格式(比如用双引号包裹整个标签、用逗号分隔键值对)会导致
Tag.Get()返回空字符串,且编译器完全不报错
reflect.StructTag 解析失败的三个高频写法
标签必须用反引号 `,且内部键值对格式严格:
- ❌
Name string "json:\"name\""—— 双引号包裹,被当作文本字面量,不是 tag - ❌
Age int `json:"age",omitempty`—— 逗号分隔,StructTag.Get("json")会返回空 - ❌
Role string `json:admin`—— 值没加双引号,Go 解析器直接丢弃该键值对 - ✅ 正确写法:
Role string `json:"admin"`或组合:Price float64 `json:"price,string,omitempty"`
多个标签共存时怎么互不干扰?
一个字段可以同时带 json:、db:、validate: 多个标签,它们彼此独立:
-
json:控制序列化行为,db:控制 SQL 映射,validate:控制校验逻辑 - 不同库只读自己关心的键,不会误读其他内容
- 注意:如果两个库都读同一个键(比如都用
form:),就得统一语义,否则行为不可控 - 示例:
ID int `json:"id" db:"user_id" validate:"required"`
自定义标签必须自己写反射逻辑吗?
是的,除非你用现成支持它的库(如 go-playground/validator 支持 validate:,sqlx 支持 db:)。想让 filtered:"true" 生效,至少得写这几行:
"true"
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











