在 Go 中,& 是取地址操作符,用于获取变量的内存地址;* 既用于声明指针类型,也用于解引用指针以访问其所指向的值——二者功能互补,不可互换。
在 go 中,`&` 是取地址操作符,用于获取变量的内存地址;`*` 既用于声明指针类型,也用于解引用指针以访问其所指向的值——二者功能互补,不可互换。
Go 语言中的 & 和 * 是指针机制的核心符号,它们语义明确、职责分明,但初学者常因名称相似(“地址”“星号”)而混淆。理解其差异是掌握内存操作、函数参数传递(如避免大对象拷贝)和结构体方法接收者设计的关键。
✅ &:取地址操作符(Address-of Operator)
& 作用于一个已存在的变量,返回该变量在内存中的地址,结果是一个指针值。它不改变原变量,仅提供其位置“门牌号”。
age := 28 addr := &age // addr 的类型是 *int,值为 age 所在内存地址
⚠️ 注意:& 只能作用于可寻址的值(如变量、结构体字段、切片元素),不能对字面量或临时值取地址,例如 &42 或 &len(arr) 是非法的。
✅ *:双重角色——类型声明符 & 解引用操作符
* 在 Go 中有两种上下文,需结合语法位置判断:
-
类型声明中(右侧):*T 表示“指向类型 T 的指针类型”
var p *string // p 是一个指针变量,类型为 *string p = &name // name 必须是 string 类型变量
-
表达式中(前缀操作符):*p 表示“解引用”,即获取指针 p 所指向内存地址中存储的实际值
name := "Alice" p := &name fmt.Println(*p) // 输出 "Alice" —— 通过 * 读取 p 指向的内容 *p = "Bob" // 修改 p 所指向的值(即 name 变为 "Bob")
? 完整示例:声明、赋值与解引用全流程
package main
import "fmt"
func main() {
x := 42 // x 是 int 类型变量,值为 42
var ptr *int // 声明 ptr 为 *int 类型(指针变量)
ptr = &x // &x → 获取 x 的地址,赋给 ptr
// 等价简洁写法:
// ptr := &x
fmt.Printf("ptr 存储的地址: %p\n", ptr) // 输出类似 0xc0000140b0
fmt.Printf("ptr 指向的值: %d\n", *ptr) // 解引用:输出 42
*ptr = 99 // 修改 ptr 所指内存中的值 → x 现在也是 99
fmt.Println("x =", x) // 输出:x = 99
}
? 关键总结
- &variable → 得到地址(生成指针值);
- *T(在 var p *T 中)→ 定义指针类型;
- *p(在 *p = ... 或 v := *p 中)→ 访问/修改指针指向的值;
- & 和 * 在语法上互为逆运算:*&x 等价于 x(只要 x 可寻址),&*p 等价于 p(只要 p 非 nil)。
掌握这对操作符,是写出高效、安全且符合 Go 惯用法(如 func updateValue(v *int))代码的基础。务必牢记:*& 出发于值,`` 归属于指针**。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











