应仅在需表达“未设置”或“函数内修改原值”时用*int;否则因拷贝成本低、指针增开销与panic风险,优先使用int。

对 Go 中的 int、bool、float64、string 等基本类型,**绝大多数场景下使用指针没有意义,反而增加风险和开销**。只有极少数明确需要“可空性”或“函数内修改原值”的场景才值得考虑。
什么时候传 *int 而不是 int?
核心判断依据就两个:是否需要表达“未设置”,或是否必须在函数内修改调用方的原始变量。
- JSON 反序列化时区分字段是否存在:比如
Age *int可以区分{"age":0}(显式设为 0)和{}(字段缺失),而Age int两者都解出0 - 函数需作为“输出参数”:例如配置解析器中,
func parseTimeout(s string, out *time.Duration) error,让调用方传入一个地址,解析成功后直接写入——这比返回time.Duration再赋值更符合某些 API 设计习惯(但非常规) - 结构体中表示可选基础字段:如
type Config struct { MaxRetries *int },允许调用方不设置该字段,后续逻辑通过if c.MaxRetries != nil判断是否启用重试
为什么通常不该用 *int?
因为 Go 的基本类型本身很小(int 通常是 8 字节),拷贝成本几乎为零;而指针引入了额外间接层、nil 检查负担、GC 压力,还容易引发 panic。
- 性能无收益:传
int是栈上复制 8 字节;传*int是复制 8 字节地址 + 额外一次内存寻址 + 潜在的堆分配(如果指针指向的是 new 出来的) - 安全风险高:解引用前若未判
nil,运行时直接 panic ——var p *int fmt.Println(*p) // panic: runtime error: invalid memory address or nil pointer dereference
- 语义混淆:
string本身是只读的 header 结构(含指针),传*string并不能让你“修改原字符串内容”,只能替换整个字符串值,且不如直接返回新string清晰
常见误用与错误现象
开发者常因“想模仿其他语言的引用传递”或“看到别人用了就跟着用”,导致写出脆弱代码。
seo特别版程序介绍:注意:普通用户建议使用淄博分类信息港程序普通版本。主要针对seo需要增加了自定义功能:自定义文件路径;自定义文件名;自定义关键字。这些功能的作用,只有自己体会了。以下是淄博分类信息港程序的介绍:淄博分类信息港程序一套现成的城市分类信息网站发布系统。发布管理房屋、人才、招租、招聘、求购、求租、搬迁、运输、二手交易、招生培训、婚介交友等各类信息的发布和查询。淄博分类信息港发布程序
立即学习“go语言免费学习笔记(深入)”;
-
误以为能修改原始字符串内容:
*string只能改它指向哪个字符串,无法像 C 那样改底层字节数组 -
忽略初始化,直接解引用:
var user struct{ Name *string } fmt.Println(*user.Name) // panic -
在 map 或 slice 中大量存
*int:每个new(int)都是一次堆分配,小对象堆化会显著抬高 GC 压力 -
接口实现不一致:如果某个方法用了
*int参数,另一个却用int,调用方容易传错,且无法通过编译器强制统一
真正需要指针语义时,优先考虑是否能用值类型 + 明确返回值替代;只有当“空/非空”语义不可省略(如数据库 NULL 映射、API 可选字段),才引入基本类型的指针——而且务必在文档和构造逻辑中明确其生命周期与 nil 含义。









