Go语言初始化结构体时何时使用&符号?两种写法的区别及适用场景
Go结构体初始化加&符号的差异与选择建议
两种写法的本质区别
- 变量类型差异
写法1中myOmUser是OmUser值类型,变量本身直接存储结构体的所有字段数据;写法2中myOmUser是*OmUser指针类型,变量仅存储结构体实际数据所在内存的地址。 - 序列化结果一致的原因
json.Marshal处理数据时会自动解引用指针,只要指针指向的结构体内容和值类型结构体的内容完全相同,最终输出的序列化结果就没有差异。 - 运行时实际差异
- 拷贝开销不同:值类型在赋值、传参、存入
interface{}类型字段时都会触发全量内存拷贝,如果结构体字段多、体积大,会产生明显的性能损耗;指针类型仅拷贝8字节(64位系统)的地址,开销极低。 - 数据共享逻辑不同:写法1中
HttpResult.Data存储的是myOmUser的独立拷贝,后续修改原myOmUser的字段不会影响Data里的内容;写法2中Data存储的是同一块内存的指针,修改原变量会同步影响Data中的数据,反之亦然。 - 空值表达能力不同:值类型
OmUser永远不会为nil,只能用字段全零的状态表示未初始化,容易和合法的零值业务数据混淆;指针类型*OmUser可以为nil,可以明确表示「无数据」的业务状态。
- 拷贝开销不同:值类型在赋值、传参、存入
实际开发选择建议
- 优先用值类型的场景:结构体体积小(总大小不超过1KB,或仅含少量基础类型字段)、不需要跨多模块共享修改同一份实例、不需要用
nil表示空状态。值类型不需要处理空指针panic风险,代码更安全,且小结构体栈分配的性能远高于指针堆分配。 - 优先用指针类型的场景:结构体体积大、需要多模块共享修改同一份实例、需要用
nil明确表示未初始化/不存在的状态、结构体绑定了需要修改自身的指针接收者方法。
内容的提问来源于stack exchange,提问作者armnotstrong
相关产品推荐
相关产品推荐

