news 2026/6/15 19:19:13

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/15 11:27:50

2025福建省文旅经济发展推介暨项目招商活动在西安举办

由省文化和旅游厅、省商务厅联合主办的2025福建省文旅经济发展推介暨项目招商活动11日在陕西省西安市举办。闽陕两省知名文旅企业、重点投资商,陕西省和西安市重点商协会负责人,福建省内各设区市和平潭综合实验区文旅部门负责人等共计240余人参加活动。福…

作者头像 李华
网站建设 2026/6/14 19:41:45

救命!这个翻译器直接把我从“语言残废”拯救了

谁懂啊家人们!出门旅游对着菜单手舞足蹈,看外文文档像看天书,开会遇到外国同事直接开启“微笑点头”模式——咱就是说,语言不通的苦,真的能让人分分钟社死!但自从我挖到这款“翻译界全能选手”,…

作者头像 李华
网站建设 2026/6/14 14:34:17

基于单片机的智能信号发生器的设计

基于单片机的智能信号发生器的设计 一、系统设计背景与需求分析 传统信号发生器多为专用仪器,存在功能固化、调节繁琐、便携性差等问题。例如,实验室常用的函数信号发生器多依赖旋钮机械调节,频率与幅值精度受限于硬件刻度,且波形…

作者头像 李华
网站建设 2026/6/15 14:03:32

Laravel 13发布后必须立即执行的缓存操作:多模态清理的3大紧急步骤

第一章:Laravel 13发布后缓存清理的紧迫性随着 Laravel 13 的正式发布,框架在底层架构、服务容器绑定机制以及配置加载策略上进行了多项优化。这些变更虽然提升了性能与可维护性,但也导致旧版本中生成的缓存文件与新版本不兼容。若在升级后未…

作者头像 李华
网站建设 2026/6/15 13:30:38

【农业物联网安全防线】:基于PHP的设备认证体系构建全记录

第一章:农业物联网安全挑战与PHP技术定位 随着农业物联网(Agri-IoT)系统的快速普及,传感器网络、自动化灌溉与远程监控等应用广泛部署于农田环境。然而,这些设备常暴露于开放物理空间中,面临数据窃取、设备…

作者头像 李华
网站建设 2026/6/15 13:49:13

深入解析Kafka核心写入逻辑

Kafka Broker 中 ReplicaManager 的核心写入逻辑,主要包含两个关键方法: appendRecords:处理 PRODUCE 请求(即生产者写入消息)deleteRecordsOnLocalLog delayedDeleteRecordsRequired:处理 DELETE_RECORDS…

作者头像 李华