必须用int或bool传参仅当需在函数内修改调用方基本类型原始值,或区分“未设置”与“设为false/0”;解引用前须判nil防panic;初始化优选&true/&false,json反序列化时*bool常因null或缺失字段保持nil。

什么时候必须用 *int 或 *bool 传参
只有当你要在函数内部修改调用方的原始值,且这个值是基本类型时,才需要传指针。Go 的参数传递永远是值拷贝,int 和 bool 拷贝成本低,但“改不了原值”是硬限制。
常见错误现象:func setFlag(b bool) { b = true } 调用后原变量没变;或者想实现“可选更新”,比如只改字段 A 不碰 B,但结构体里 B 是 bool,默认零值 false 和“用户明确设为 false”无法区分。
- API 接收配置时,需区分“未设置”和“设为 false/0” → 用
*bool/*int - 回调函数中需就地修正某个计数器或开关状态 → 传
*int或*bool - 避免为单个基本类型专门定义新结构体,指针是最轻量的“可空性”表达
nil 的 *bool 和 *int 怎么安全解引用
解引用前不检查 nil 会 panic:panic: runtime error: invalid memory address or nil pointer dereference。这不是语法错误,而是在运行时炸,容易漏测。
使用场景:HTTP API 解析 JSON 请求体,字段声明为 *bool,前端可能完全不传该字段(后端收到 nil),也可能传 {"enabled": null} 或 {"enabled": false}。
立即学习“go语言免费学习笔记(深入)”;
- 永远先判
!= nil再取值:if enabled != nil { use(*enabled) } - 不要直接写
val := *enabled,除非你 100% 确保非空(比如刚 new 出来) - 给默认值常用模式:
v := false; if enabled != nil { v = *enabled }
用 new(bool) 还是 &false 初始化 *bool
两者都合法,但语义和可读性差很多。new(bool) 返回指向零值 false 的指针,&false 是取一个临时变量地址——后者更直观,也更常被静态分析工具(如 staticcheck)推荐。
性能上无差异,但兼容性有坑:如果用 &false 初始化后长期持有该指针,而该 false 是局部变量,Go 编译器会自动将其逃逸到堆,实际效果和 new 一样;但代码意图更清晰。
- 初始化即用、生命周期短 → 用
&true或&false - 初始化后要塞进 map 或结构体长期存 → 用
new(bool)更显式表明“我要一个堆上 bool 指针” - 别写
var b bool; pb := &b,纯属多此一举
JSON 反序列化时 *bool 字段为啥总变成 nil
因为 JSON 中 null、缺失字段、甚至空字符串都不会触发 *bool 的赋值,json.Unmarshal 默认只对非 nil 值解包。这是最常被忽略的兼容性细节。
典型表现:前端发 {"active": null},Go 结构体字段是 Active *bool,结果 Active 是 nil,不是指向 false 的指针。
- 要支持
null → *bool映射,得自定义UnmarshalJSON方法 - 第三方库如
github.com/mitchellh/mapstructure默认也不处理,得配DecodeHook - 简单 workaround:接收为
interface{},手动判断nil/bool类型再赋值
复杂点在于,这问题不会报错,只会静默失效。上线后发现“前端关了开关,后端日志里还是 true”,八成是这里卡住了。










