news 2026/8/22 19:39:55

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/8/19 17:20:48

Kafka副本管理核心:ReplicaManager揭秘

Apache Kafka Broker 端核心组件 ReplicaManager它是 Kafka 实现 副本管理、ISR(In-Sync Replicas)维护、Leader/Follower 同步、日志存储协调 的中枢。 下面我将从 整体定位、关键字段、核心机制、工作流程 四个维度,帮你系统性理解这段代码…

作者头像 李华
网站建设 2026/8/22 5:10:24

西门子smart SB CM01与3台台达DT330温控器485通讯程序开发记录

西门子smart SB CM01与3台台达DT330温控器485通讯程序(XMZ200-4)器件:西门子s7 200 smart PLC,扩展模块SB CM01,3台台达DT330温控器。 昆仑通态触摸屏(带以太网),中途可以加路由器 控制方式:触摸屏与plc以太网通讯&…

作者头像 李华
网站建设 2026/8/22 5:25:38

大模型从0到精通:蒙眼下山法-AI如何一步步“摸索”到最优解?

本文是《大模型从0到精通》系列第一卷“奠基篇”的第三章。上章我们建立了“错题山谷”和评分标准(损失函数),但怎么找到山谷最低点?本章将引入梯度下降——AI在“错题山谷”中蒙眼下山的寻路算法,这是驱动所有AI(包括千亿参数大模型)学习的核心引擎。 一、蒙眼下山:一…

作者头像 李华
网站建设 2026/8/21 20:22:42

接口自动化测试中解决接口间数据依赖

在实际的测试工作中,在做接口自动化测试时往往会遇到接口间数据依赖问题,即API_03的请求参数来源于API_02的响应数据,API_02的请求参数又来源于API_01的响应数据。 因此通过自动化方式测试API_03接口时,需要预先请求API_02接口&a…

作者头像 李华