当前位置: 首页 > news >正文

golang语法-----指针

一、核心语法

1、取地址符 &,用在一个变量前面,获取这个变量的内存地址。

package mainimport "fmt"func main() {name := "Alice" // 变量 name,它的值是 "Alice"// &name 获取变量 name 的内存地址// p 是一个指针变量,它存储了 name 的地址// p 的类型是 *string,读作 "string 类型的指针"p := &name fmt.Println("变量 name 的值:", name)fmt.Println("变量 name 的内存地址:", p) // 会打印一个像 0x... 的十六进制地址
}

2、解引用符 *,用在一个指针变量前面,获取该指针指向的地址上存储的那个值。

    // ... p 是指向 name 的指针// *p 表示“访问 p 指针指向的那个变量的值”fmt.Println("通过指针 p 访问到的值:", *p) // 输出: Alice// 通过指针修改原变量的值*p = "Bob" // 这等价于 name = "Bob"fmt.Println("修改后,原变量 name 的值:", name) // 输出: Bobfmt.Println("修改后,通过指针 p 访问到的值:", *p) // 输出: Bob

3、空指针,当一个指针被定义后没有分配到任何变量时,它的值为 nil

package mainimport "fmt"func main() {var p *stringfmt.Println(p)fmt.Printf("p的值是%s/n", p)if p != nil {fmt.Println("非空")} else {fmt.Println("空值")}
}

4、安全特性

(1)无指针运算:不允许像在 C 语言里那样对指针进行加减运算(例如 p++),杜绝了一大类内存访问错误。

你只能从一个指针移动到另一个指针(通过 unsafe 包,但新手绝对不要碰)。

(2)无法获取任意地址的指针: 不能将一个整数强制转换成指针,无法指向任意内存地址。

二、指针的应用

1、在函数间共享和修改数据

Go 语言的函数参数传递都是值传递,意味着把一个变量传给函数时,函数得到的是这个变量的一个副本,比如:

func changeValue(num int) {num = 100 // 这里修改的是 num 的副本,不会影响外面的 a
}func main() {a := 10changeValue(a)fmt.Println("a 的值是:", a) // 输出: a 的值是: 10
}

通过传递变量的地址(指针),函数就可以通过地址直接操作原始变量,而不是它的副本

// 函数接收一个 *int 类型的参数,即一个指向 int 的指针
func changeValueByPointer(ptr *int) {*ptr = 100 // 通过指针,直接修改了指针指向地址上的值
}func main() {a := 10changeValueByPointer(&a) // 把 a 的内存地址传给函数fmt.Println("a 的值是:", a) // 输出: a 的值是: 100
}

2、指向结构体的指针

type Person struct {Name stringAge  int
}func main() {p := Person{Name: "David", Age: 40}// a. 创建一个指向结构体的指针ptr := &p// b. 访问结构体字段// 标准写法是 (*ptr).Name,需要解引用再访问字段fmt.Println("姓名:", (*ptr).Name)// c. 语法糖 (Syntactic Sugar)// Go 语言为了方便,允许你直接用 ptr.Name 来代替 (*ptr).Name// 编译器会自动帮你转换。这种写法更常用!fmt.Println("姓名 (语法糖):", ptr.Name) // 通过指针修改字段ptr.Age = 41fmt.Println("修改后的年龄:", p.Age) // 输出: 41
}

3、new 函数:创建指针

除了用 & 获取已有变量的地址,你还可以用内置的 new 函数来创建一个指向某个类型零值的指针。

new(T) 的作用是:

  1. 分配一块内存来存储 T 类型的零值。
  2. 返回这块内存的地址,即一个 *T 类型的指针。
// 创建一个指向 int 零值 (0) 的指针
var p1 = new(int) 
fmt.Println("p1 指向的值:", *p1) // 输出: 0
*p1 = 123
fmt.Println("修改后 p1 指向的值:", *p1) // 输出: 123// 创建一个指向 Person 零值的指针
var p2 = new(Person)
p2.Name = "Eve"
fmt.Println("p2 指向的人:", *p2) // 输出: {Eve 0}

http://www.lryc.cn/news/590192.html

相关文章:

  • 笔试——Day10
  • 简单易懂,什么是连续分配管理方式
  • Qt 将触摸事件转换为鼠标事件(Qt4和Qt5及以上版本)
  • Java线程创建与运行全解析
  • DuckDB 高效导入 IPv6 地址数据的实践与性能对比
  • #Datawhale组队学习#7月-强化学习Task1
  • java解析word文档
  • 使用JS编写一个购物车界面
  • C++ 面向对象
  • 第2章通用的高并发架构设计——2.3 高并发读场景方案2:本地缓存
  • 开源 python 应用 开发(七)数据可视化
  • Linux 定时器应用示例(修正版)
  • GIT版本回退
  • Python中可以反转的数据类型
  • GaussDB 数据库架构师修炼(五) 存储容量评估
  • 搜索框的显示与隐藏(展开与收起)
  • el-input 回显怎么用符号¥和变量拼接展示?
  • openEuler 22.03 LTS Rootless Docker 安装指南
  • MongoDB复杂查询 聚合框架
  • 洛谷 P11247 [GESP202409 六级] 算法学习-普及/提高-
  • pymongo库:简易方式存取数据
  • ETL还是ELT,大数据处理怎么选更靠谱?
  • 步态循环(Gait Cycle)
  • 【MySQL事务和锁】回顾事务
  • 图像质量评价(Image Quality Assessment,IQA)
  • 调试bug记录
  • 【基于飞浆训练车牌识别模型】
  • Docker——Redis
  • 【C语言网络编程】HTTP 客户端请求(发送请求报文过程)
  • Mybatis07-缓存