Go 结构体
Go 结构体(struct)是 Go 语言的复合数据类型,用来把若干个不同类型的字段聚合成一个整体。定义方式是 type User struct { Name string; Age int },之后就能像 u.Name 这样访问字段。它是 Go 组织数据的核心手段,常用于描述一条记录、一个 API 请求/响应或配置项。Go 没有类和继承,通常靠结构体的嵌入(组合)来复用字段和方法。
字段名后反引号里的内容叫 struct tag,是一串附加元信息,例如 Name string `json:"name"`。tag 本身不产生任何行为,要靠库通过反射(reflect)读取后才生效。最常见的是 encoding/json:它按 json tag 决定序列化时的字段名,还支持 omitempty(空值时省略)、-(忽略该字段)等选项。把一段 JSON 转成对应的 Go 结构体(含 tag)正是 json-to-go 这类工具做的事。
几个容易踩的点:
- 字段首字母大写才是导出的,
json等外部库只能处理导出字段,小写字段不会被序列化。 - struct 是值类型,赋值和函数传参都会整体拷贝;想共享或修改原值要用指针
*User。 - tag 的格式(键、引号、空格)有讲究,写错不会报错,只是被静默忽略。
常见问题
struct tag 里的 json:"name" 到底起什么作用?
它是给反射读取的元信息,encoding/json 会据此把该字段序列化/反序列化为 JSON 里的 name。tag 本身不执行逻辑,只有支持它的库读取后才生效。
为什么我的字段没被 JSON 序列化出来?
多半是字段名首字母小写。Go 只有导出字段(首字母大写)能被 encoding/json 访问,小写字段会被直接跳过;加了 json tag 也没用。
结构体是值类型还是引用类型?传参时会被修改吗?
是值类型,赋值和传参都会整体拷贝,函数内改动不影响原变量。若要修改原值或避免大结构体拷贝开销,应传指针 *T。