如何在Golang中使用指针_Golang指针定义与使用方法

发布时间 - 2026-01-31 00:00:00    点击率:
Go指针是安全可控的内存引用,声明为T,需避免nil解引用;传指针可修改原变量,slice/map/channel本身是引用类型,无需额外加。

Go 语言中的指针不是“C 风格的危险工具”,而是明确、可控的内存地址引用——只要不越界解引用或传 nil,它就是安全的。

如何声明和初始化一个指针变量

Go 的指针类型语法是 *T,表示“指向类型 T 的值的地址”。声明时必须指定所指类型,不能像 C 那样用 void* 混用。

常见错误:直接对未初始化的指针解引用(panic: runtime error: invalid memory address)。

  • var p *int 声明了一个 int 类型指针,但此时 p == nil,不能直接写 *p = 10
  • 正确初始化方式之一:num := 42; p := &num& 取地址,p 现在指向 num 的内存位置
  • 也可用 new():p := new(int),等价于 var v int; p := &v,返回已分配零值的地址

函数参数传指针 vs 传值的区别

Go 默认按值传递——函数内修改形参不会影响实参。想让函数修改原始变量,必须传指针。

典型场景:修改结构体字段、避免大对象拷贝、实现“输出参数”语义。

  • 传值:func modify(x int) { x = 100 } → 调用后原变量不变
  • 传指针:func modify(x *int) { *x

    = 100 }
    → 必须用 *x 解引用赋值
  • 结构体传指针更常见:func (u *User) setName(n string) { u.name = n },否则方法无法修改接收者字段

nil 指针检查与常见 panic 场景

Go 不做空指针自动防护,*pp == nil 时立即 panic。这要求你主动判断,而不是依赖运行时兜底。

容易踩坑的地方:函数返回指针但没检查是否为 nil;接口变量底层是 nil 指针却直接调用方法。

  • 安全解引用前务必检查:if p != nil { val := *p }
  • 从 map、channel、slice 中取值再取地址?注意它们可能返回零值,&m["key"] 在 key 不存在时会取到 &zeroValue,但该地址有效;而 m["key"] 本身是零值,取地址没问题,但若原 map 值是 struct 指针,要小心嵌套 nil
  • 方法接收者为指针时,nil 接收者调用方法不会 panic —— 除非方法内部访问了 *receiver 字段(比如 receiver.field

切片、map、channel 本身已经是引用类型,不需要额外加 *

新手常误以为“要修改 slice 就得传 *[]T”,其实完全没必要。slice 本身包含指向底层数组的指针、长度和容量,传 slice 就是传这三个字段的副本,修改元素或用 append 改变底层数组内容都生效;但若想改变 slice 头部(如让它指向新数组),才需要传 *[]T

  • func update(s []int) { s[0] = 999 } → 原 slice 第一个元素被改
  • func reassign(s *[]int) { *s = []int{1,2,3} } → 原 slice 变成新切片
  • map 和 channel 同理:传 map[string]int 即可增删改查;只有想让函数替换整个 map 变量(比如清空并重置为新 map)才需 *map
package main

import "fmt"

type User struct {
	Name string
}

func main() {
	age := 25
	p := &age
	fmt.Println(*p) // 25

	// 修改原变量
	*p = 26
	fmt.Println(age) // 26

	u := User{Name: "Alice"}
	pu := &u
	pu.Name = "Bob" // 等价于 (*pu).Name = "Bob"
	fmt.Println(u.Name) // Bob
}

指针真正的复杂点不在语法,而在你是否清楚某个值的生命周期是否覆盖指针的使用范围——比如返回局部变量地址(Go 编译器会自动逃逸分析并堆分配,通常安全),但手动管理 C 内存或 CGO 场景下,这点就极易出错。


# go  # golang  # app  # 工具  # ai  # 区别  # golang指针  # String  # if  # Error  # 局部变量  # 结构体  # int  # void  # 指针  # 接口  #   # 引用类型  # 指针类型  # 输出参数  # Struct  # var  # 值传递  # 形参  # 实参  # 空指针  # 切片  # nil  # append  # map  # channel  # 对象  # 想让  # 第一个  # 不需要  # 而在  # 不存在  # 就得  # 你是否  # 让它  # 要小心  # 没必要 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  jQuery中的100个技巧汇总  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  iOS中将个别页面强制横屏其他页面竖屏  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  EditPlus中的正则表达式 实战(4)  Java垃圾回收器的方法和原理总结  如何彻底卸载建站之星软件?  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  Android使用GridView实现日历的简单功能  网易LOFTER官网链接 老福特网页版登录地址  Android利用动画实现背景逐渐变暗  PHP正则匹配日期和时间(时间戳转换)的实例代码  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  如何确保西部建站助手FTP传输的安全性?  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  装修招标网站设计制作流程,装修招标流程?  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  Laravel怎么连接多个数据库_Laravel多数据库连接配置  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  如何用AWS免费套餐快速搭建高效网站?  Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南  Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门  Python3.6正式版新特性预览  如何在阿里云部署织梦网站?  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Laravel怎么判断请求类型_Laravel Request isMethod用法  jQuery validate插件功能与用法详解  如何彻底删除建站之星生成的Banner?  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  php打包exe后无法访问网络共享_共享权限设置方法【教程】  如何在建站之星绑定自定义域名?  利用vue写todolist单页应用  html5的keygen标签为什么废弃_替代方案说明【解答】  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  长沙做网站要多少钱,长沙国安网络怎么样?  详解MySQL数据库的安装与密码配置  Linux系统命令中tree命令详解  如何在建站宝盒中设置产品搜索功能?  如何在服务器上配置二级域名建站?  如何在IIS服务器上快速部署高效网站?  Laravel路由怎么定义_Laravel核心路由系统完全入门指南  如何在万网自助建站平台快速创建网站?  如何在自有机房高效搭建专业网站?  Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】  SQL查询语句优化的实用方法总结  香港服务器选型指南:免备案配置与高效建站方案解析  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信