go语言指针常见操作方法

 更新时间:2026年05月09日 10:37:10   作者:讲不出  再见  
指针是存储变量内存地址的变量,声明格式为`*T`,指针用于函数间共享数据、传递结构体等,本文给大家介绍go语言指针常见操作方法,感兴趣的朋友一起看看吧

什么是指针?

指针是存储一个变量的内存地址的,声明一个指针变量的格式如下:

// ptr是指针变量名,*表示是指针类型,*int表示存储的是一个int类型变量的内存地址
var ptr *int

1、关键操作符

符号名称作用示例
&取址符获取变量在内存中的地址,返回指针类型ptr := &num (获取 num 的地址)
*解引用符

1. ‌声明时‌:表示指针类型(如 *int)

2. ‌使用时‌:获取或修改指针指向的具体值

val := *ptr (读取ptr指向的int变量值)

*ptr = 100 (修改ptr指向的int变量值为100)

2、常见操作

package main
import "fmt"
func main() {
    // 1.定义普通变量
    num := 100
    fmt.Printf("普通变量值: %d, 地址: %p\n", num, &num)
    // 2. 声明并初始化指针
    var ptr *int = &num // ptr 存储的是 num 的内存地址
    // 3. 解引用:读取和修改
    fmt.Printf("指针指向的值: %d\n", *ptr) // 输出 100
    *ptr = 200 // 通过指针修改原始变量的值
    fmt.Printf("修改后原始变量值: %d\n", num) // 输出 200,证明原值被改变
}

3、空指针

当指针变量未初始化时,默认为空指针,nil。

go语言底层将nil视为地址为0的特殊变量。

所以,空指针 ptr == nil 为true,但是在打印ptr指向的内存地址时,打印出的是 0x0【就是0】

危险操作:对 nil 指针进行解引用(如 *ptr)会导致程序运行时崩溃(panic: invalid memory address or nil pointer dereference)。

package main
import "fmt"
func main() {
	var ptr *int
	if ptr == nil {
		fmt.Printf("%p", ptr)
	} 
}

4、指针的使用场景

4.1、在函数间共享数据并修改原值

Go 语言默认参数传递是‌值传递‌(拷贝副本)。如果希望在函数内部修改外部变量的值,必须传递指针。

func increment(ptr *int) {
    *ptr++ // 修改指针指向的原始值
}
func main() {
    count := 10
    increment(&count) // 传入地址
    fmt.Println(count) // 输出 11
}

4.2、避免大型数据结构的拷贝开销

对于大型结构体(Struct)或数组,值传递会复制整个数据结构,消耗内存和 CPU。传递指针仅复制一个地址(64位系统占8字节),效率极高。

type BigData struct {
    Items int
}
// 使用指针接收,避免拷贝 10000 个 int
func process(data *BigData) {
    // 处理逻辑
}

5、注意事项

1. 不可取地址的情况

你不能对以下对象使用 & 取地址,否则编译报错 cannot take the address of ...

  • 字面量/常量‌:&42&"hello" 是错误的。
  • Map 的值‌:&m["key"] 是错误的。因为 Map 的值可能随时移动或不存在,Go 禁止直接取 Map 值的地址。如果需要,先将值赋给临时变量再取址。
  • 函数返回值‌:通常情况下,不能直接对函数返回值取地址(除非返回的是指针或可寻址变量)。

2. 切片、Map 和 Channel 的特殊性

  • 切片(Slice)、Map 和 Channel 在 Go 中本身就是‌引用类型‌(底层实现包含指针)。
  • 无需传指针‌:在函数间传递切片或 Map 时,通常直接传递值即可。函数内部对元素内容的修改会反映到原变量上。
  • 例外‌:如果你需要在函数内改变切片的‌长度‌或‌容量‌(例如 append 导致底层数组重新分配),或者替换整个 Map 对象,则需要传递指向切片或 Map 的指针(如 *[]int),但这在日常开发中较少见。

3. 内存逃逸与性能

  • 栈与堆‌:Go 编译器会自动进行“逃逸分析”。如果局部变量的地址被返回或传递给其他 goroutine,该变量会分配到堆上,增加垃圾回收(GC)压力。
  • 适度使用‌:不要滥用指针。对于小的基本类型(int, bool, small struct),值传递往往比指针传递更快,因为指针涉及间接寻址和可能的堆分配。

4. 原子指针与 unsafe

  • sync/atomic.Pointer 提供了无锁的原子指针操作,适用于高并发场景下的状态切换。
  • unsafe.Pointer 允许绕过类型系统进行指针转换,极其危险,不参与 GC 生命周期检查,容易导致悬垂指针或内存破坏。除非编写底层库或驱动,否则严禁在业务代码中使用。

到此这篇关于go语言指针常见操作方法的文章就介绍到这了,更多相关go语言指针内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅析Go 字符串指纹

    浅析Go 字符串指纹

    这篇文章主要介绍了Go 字符串指纹的相关资料,帮助大家更好的理解和学习go语言,感兴趣的朋友可以了解下
    2020-09-09
  • golang时间及时间戳的获取转换

    golang时间及时间戳的获取转换

    本文主要介绍了golang时间及时间戳的获取转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Go语言常见哈希函数的使用

    Go语言常见哈希函数的使用

    哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。具体的介绍网上有很详细的描述,如闲聊哈希表 ,这里就不再累述了;
    2015-03-03
  • Golang使用zlib压缩和解压缩字符串

    Golang使用zlib压缩和解压缩字符串

    本文给大家分享的是Golang使用zlib压缩和解压缩字符串的方法和示例,有需要的小伙伴可以参考下
    2017-02-02
  • go语言静态库的编译和使用方法

    go语言静态库的编译和使用方法

    这篇文章主要介绍了go语言静态库的编译和使用方法,本文以windows平台为例,通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • golang 用msgpack高效序列化的案例

    golang 用msgpack高效序列化的案例

    msgpack是一个非常受欢迎的Go序列化库,具有很好的跨语言支持,这篇文章主要介绍了golang 用msgpack高效序列化的相关知识,需要的朋友可以参考下
    2023-05-05
  • Golang获取目录下的文件及目录信息操作

    Golang获取目录下的文件及目录信息操作

    这篇文章主要介绍了Golang获取目录下的文件及目录信息操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go正则表达式匹配字符串,替换字符串方式

    Go正则表达式匹配字符串,替换字符串方式

    介绍了Go语言中使用正则表达式进行字符串匹配和替换的方法,包括匹配单个子字符串和所有子字符串,个人经验分享,旨在为读者提供实用的编程技巧,并鼓励大家支持脚本之家
    2025-02-02
  • golang中snappy的使用场合实例详解

    golang中snappy的使用场合实例详解

    在java 和go语言 大字符传达的时候, 采用snappy 压缩 解压缩是最好的方案。下面这篇文章主要给大家介绍了关于golang中snappy使用场合的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-12-12
  • golang批量执行任务的通用模板分享

    golang批量执行任务的通用模板分享

    这篇文章主要为大家详细介绍了golang实现批量执行任务的通用模板,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2023-11-11

最新评论