如何使用Golang操作指针变量_Golang解引用与赋值实践
技术百科
P粉602998670
发布时间:2026-01-01
浏览: 次 Go指针是类型安全的引用机制,不可进行指针算术或整数强制转换;必须指向可寻址变量,nil解引用会panic;使用前需判空,结构体指针字段零值为nil;适用场景是需修改原值或避免大对象拷贝。
什么是 Go 中的指针变量,它和 C 有什么不同
Go 的指针不是内存地址的任意操作工具,而是类型安全的引用机制。声明 *int 表示“指向 int 的指针”,不能像 C 那样做指针算术(比如 p + 1),也不能把整数强制转成指针((*int)(unsafe.Pointer(uintptr(0x1234))) 属于 unsafe 范畴,非常规用法)。
最常见误判是认为 &x 总是返回“有效地址”——其实如果 x 是零值且未被取址过,编译器可能将其分配在只读段或直接优化掉,导致运行时报错或行为异常(尤其在闭包、切片底层数组中)。
- Go 指针必须指向一个已定义、可寻址的变量(即不能对字面量、函数返回值、map value 直接取址)
-
nil指针解引用会 panic:panic: runtime error: invalid memory address or nil pointer dereference - 结构体字段若为指针,其默认零值是
nil,不是空结构体
如何安全地解引用指针并赋值
解引用用 * 操作符,但前提是该指针非 nil。直接写 *p = 42 前,务必检查 p != nil,否则程序崩溃。
常见场景是函数接收指针参数并修改原值,例如:
func increment(p *int) {
if p == nil {
return // 或 panic("p is nil")
}
*p++
}
注意:传入 &x 才能修改 x;若传 nil 或未初始化的指针,*p 就是非法操作。
- 不能对未初始化的指针变量解引用:
var p *int; *p = 1→ panic - 可以对新分配的堆内存解引用:
p := new(int); *p = 1✅ - 可以用
new(T)或&T{}初始化指针,二者等价于分配零值并返回其地址
struct 字段含指针时的典型陷阱
当结构体某个字段是指针类型,它的零值是 nil,而非该类型的零值。比如 type User struct { Name *string },新建 u := User{} 后,u.Name 是 nil,此时 *u.Name 会 panic。
正确做法是在使用前确保指针已初始化:
name := "Alice"
u := User{Name: &name}
fmt.Println(*u.Name) // 输出 Alice
- JSON 反序列化时,
*string字段若 JSON 中对应字段缺失或为null,反序列化后仍为nil,需额外判断 - 数据库 ORM(如 GORM)映射
*string字段时,空字符串和 NULL 会被区分开:NULL →nil,空字符串 → 指向空字符串的指针 - 不要用
== ""判断*string是否为空,先判!= nil,再判*s == ""
什么时候该用指针,什么时候不该用
核心原则:是否需要共享/修改原始值,以及
值的大小是否值得避免拷贝。
小类型(int、bool、struct{int;bool})传值开销极小,用指针反而增加间接访问成本;大结构体(含 slice/map/channel/interface 或大量字段)传指针更合理。
- 方法接收者用指针:想修改接收者字段,或结构体较大
- 函数参数用指针:需修改调用方变量,或避免复制大对象(如
[]byte底层数据不复制,但 slice header 本身很小;真正要避免复制的是大 struct) - 返回局部变量地址安全:Go 编译器会自动做逃逸分析,把本该在栈上的变量挪到堆上,所以
func newInt() *int { v := 42; return &v }是合法的
最容易被忽略的是:指针带来的是“可变性共享”,不是“性能银弹”。滥用指针会让数据流向难以追踪,调试时尤其难定位谁改了哪个字段。
# 是在
# 的是
# 也不
# 可以用
# 能对
# 什么时候
# 工具
# win
# js
# json
# go
# golang
# Error
# 对象
# 堆
# String
# int
# 指针
# 字符串
# nil
# 序列化
# 数据库
# 栈
# pointer
# Interface
# var
# NULL
# 结构体
# Struct
# 切片
# map
# channel
# 指针类型
# 空字符串
# 闭包
# 该用
# bool
# 局部变量
# 原值
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- 如何使用正则表达式提取以编号开头、后接多个注解的逻
- Linux怎么禁止Root用户远程登录_Linux
- 如何有效拦截拼接式恶意域名的垃圾信息
- Win11怎么开启剪贴板历史记录_Windows1
- 如何在Golang中处理模块冲突_解决依赖版本不兼
- Win11怎么清理C盘虚拟内存_Win11清理虚拟
- Win10电脑怎么设置休眠快捷键_Windows1
- Windows10电脑怎么查看硬盘通电时间_Win
- php订单日志权限怎么设_php订单日志文件权限设
- PHP的FastAdmin架构适合二次开发吗_特点
- Win11怎么关闭防火墙通知_屏蔽Win11安全中
- Win11时间格式怎么改成12小时制 Win11时
- Win11怎么关闭任务栏小组件_Windows11
- SAX解析器是什么,它与DOM在处理大型XML文件
- Windows10系统怎么查看运行时间_Win10
- php增删改查报错1054怎么办_字段名错误排查修
- 如何在Golang中处理JSON字段缺失_Gola
- Python对象生命周期管理_创建销毁解析【教程】
- c++中的std::conjunction和std
- Win10如何关闭安全中心所有通知 Win10禁用
- Mac如何备份到iCloud_Mac桌面与文稿文件
- Win11开机速度慢怎么优化_Win11系统启动加
- 一文教你快速开通网站LOGO图
- Windows 11如何查看系统激活密钥_Wind
- C#如何序列化对象为XML XmlSerializ
- Win10怎么卸载剪映_Win10彻底卸载剪映方法
- Win11怎么设置麦克风权限_允许应用访问Win1
- Go 语言标准库为何不提供泛型 Contains
- MAC如何启用访达侧边栏显示_MAC Finder
- c++如何判断文件是否存在_c++ filesys
- Win11声音太小怎么办_Windows 11开启
- 企业SEO优化选择网站建设模板的技巧
- c++20的std::format怎么用 比pri
- Python异步网络编程_aiohttp说明【指导
- php下载安装包怎么选_threadsafe与nt
- PHP的Workerman对架构扩展有啥帮助_应用
- 如何使用Golang开发基础文件下载功能_Gola
- 如何在包含多值的列中精准搜索指定演员?
- Win11任务栏颜色怎么改_Win11自定义任务栏
- Windows如何设置登录时的欢迎屏幕背景?(锁屏
- c++中如何使用虚函数实现多态_c++多态性实现原
- Win11应用商店下载慢怎么办 Win11更改DN
- Win10怎样清理C盘爱奇艺缓存_Win10清理爱
- Windows 11如何开启文件夹加密(EFS)_
- 如何在 Go 后端安全获取并验证前端存储的 JWT
- Win10怎样设置闹钟贪睡时间 Win10闹钟贪睡
- Win11怎么关闭系统透明度_Windows11个
- Win10怎么卸载鲁大师_Win10彻底卸载鲁大师
- 如何使用Golang实现路由参数绑定_使用Mux和
- Win10怎样卸载iTunes_Win10卸载iT

QQ客服