news 2026/6/10 23:15:48

Go 语言指针

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Go 语言指针

Go 里的指针不复杂,但非常实用,不像 C/C++ 那么危险,也不像 Java 那样完全看不到。

一、Go 指针是什么

1. 指针的本质

指针 = 变量的内存地址

var a int = 10 var p *int = &a
  • a:值是10

  • &a:a 的地址

  • p:指向a的指针

  • *p:通过指针访问a的值

fmt.Println(a) // 10 fmt.Println(p) // 0xc00001a0a8(地址) fmt.Println(*p) // 10

口诀:
& 取地址,解引用*

2. Go 指针的“安全边界”

和 C/C++ 不同,Go:

  • 不能指针运算(p++不存在)

  • 不能随便转类型

  • 有 GC(不用手动 free)

  • 空指针是nil

var p *int fmt.Println(p == nil) // true

二、Go 指针使用场景

1. 修改函数外的变量(非常核心)

❌ 值传递(改不到外面):

func add(a int) { a++ } func main() { x := 10 add(x) fmt.Println(x) // 10 }

✅ 指针传递:

func add(a *int) { *a++ } func main() { x := 10 add(&x) fmt.Println(x) // 11 }

Go 只有值传递,但“指针的值”可以指向同一块内存

2 结构体 + 指针(Go 的高频用法)

type User struct { Name string Age int } func grow(u *User) { u.Age++ } func main() { u := User{Name: "Tom", Age: 18} grow(&u) fmt.Println(u.Age) // 19 }

注意: Go 一个很贴心的地方:

u.Age++ // 等价于 (*u).Age++

Go 自动帮解引用,不需要满屏*

3. new / & 的区别

p1 := new(int) // *int,值是 0 p2 := &User{} // *User

等价写法:

var a int p := &a

一般习惯:

  • 基本类型:&

  • 结构体:&User{}或构造函数

三、Go 指针的核心使用场景

场景 1:需要修改对象本身(最常见)

func updateName(u *User) { u.Name = "Jack" }

场景 2:避免大对象拷贝(性能 & 内存)

type BigStruct struct { Data [100000]int } func process(b *BigStruct) { // 不拷贝 100000 个 int }

场景 3:区分“没传”和“传了零值”

这个在 API / JSON / DB 特别重要

type Req struct { Age *int `json:"age"` }
  • nil→ 前端没传

  • 0→ 前端明确传了 0

场景 4:方法接收者用指针(Go 面向对象)

func (u *User) Grow() { u.Age++ }

什么时候用指针接收者?

  • 需要修改对象

  • 结构体比较大

  • 保证方法一致性(推荐)

官方建议:一个结构体,要么全指针接收者,要么全值接收者

场景 5:与 interface 配合

type Writer interface { Write() } type File struct{} func (f *File) Write() {} var w Writer w = &File{} // 正确

这样不行,因为方法在*File上:

w = File{} // 没实现接口

场景 6:并发 & 共享状态

需谨慎使用

var count int var mu sync.Mutex func inc() { mu.Lock() count++ mu.Unlock() }

虽然不是“显式指针”,但底层都是共享内存 + 地址

四、Go 指针 vs Java/C++

对比GoJavaC++
手动内存
指针运算
空指针nilnullnullptr
参数传递值传递值传递(引用语义)值/引用

Go 指针 = “受控版 C 指针 + Java 引用的灵活性”

五、新手常见坑

❌ 对 map / slice 再取指针

func f(m *map[string]int) // 一般没必要

因为:

  • map / slice 本身就是“引用类型”

  • 直接传就能改

❌ nil 指针解引用

var u *User u.Age = 10 // panic

一定要先初始化。

六、总结

Go 指针的目标只有三个:

  1. 修改原数据

  2. 减少拷贝

  3. 表达“可选值”

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 17:50:55

谷歌创始人布林:当年发完Transformer论文,我们太不当回事了

在斯坦福大学工程学院百年庆典的收官活动上,谷歌联合创始人谢尔盖・布林重返母校,与校长 Jonathan Levin 以及工程学院院长 Jennifer Widom 展开了一场对谈。现在的大学生该选什么专业?未来一百年的大学会是什么样子?业界 AI 如此…

作者头像 李华
网站建设 2026/6/10 20:08:42

一文读懂手持式负氧离子检测仪

手持式负氧离子检测仪是一种利用电容式吸入法原理,实时监测空气中负氧离子浓度的便携设备,具备高精度、便携性、多功能等特点,适用于环境监测、室内空气质量检测、产品效能评估等多个场景。一、工作原理采用“电容式吸入法”原理进行负离子检…

作者头像 李华
网站建设 2026/6/10 12:18:25

基于51单片机实现俄罗斯方块游戏的设计

基于51单片机实现俄罗斯方块游戏的设计 一、系统设计背景与需求分析 俄罗斯方块作为经典益智游戏,传统实现多依赖专用游戏机或计算机平台,存在体积大、成本高、便携性差等问题。基于51单片机设计俄罗斯方块游戏,可利用其低成本、低功耗、接口…

作者头像 李华
网站建设 2026/6/10 18:59:24

基于Arduino单片机的输液监测报警控制系统设计

第一章 研究背景与设计目标 全球每年因输液异常(如滴速失控、空气栓塞、药液输尽)导致的医疗事故占比达12%,传统人工监护存在效率低、误差大等问题。本系统以Arduino为核心,构建“实时监测-智能控制-主动报警”的输液安全方案&…

作者头像 李华
网站建设 2026/6/10 17:05:52

基于单片机控制的智能疏散系统设计

第一章 系统整体架构设计 基于单片机控制的智能疏散系统,核心目标是在紧急情况下(如火灾、地震)为人员提供精准疏散指引,整体架构分为环境监测模块、核心控制模块、指示引导模块、报警模块及通信模块五大单元。环境监测模块实时采…

作者头像 李华
网站建设 2026/6/10 17:37:43

分析openstack中快照占用存储空间问题

在私有云平台的运维过程中,总能遇见平台存储资源不够用的情况,大多数人的选择就是优先清理虚拟机的快照,把长时间不用的快照删除,来释放存储空间,这个方法是否能是否多余的存储空间呢?那快照的存储到底是存放在哪里?是否占用大量的存储空间? 下面我们从云平台创建虚拟…

作者头像 李华