Golang指针使用指南
指针基础
指针是存储变量内存地址的特殊变量类型,在Golang中使用*声明指针类型,使用&获取变量地址。
基本用法
package main
import "fmt"
func main() {
var num int = 42
var ptr *int = &num
fmt.Println("变量值:", num) // 42
fmt.Println("变量地址:", &num) // 0xc0000180a8
fmt.Println("指针值:", ptr) // 0xc0000180a8
fmt.Println("指针指向的值:", *ptr) // 42
// 通过指针修改变量值
*ptr = 100
fmt.Println("修改后的值:", num) // 100
}
指针操作
1. 指针声明和初始化
// 方式1:先声明后赋值
var ptr1 *int
num := 10
ptr1 = &num
// 方式2:声明时初始化
ptr2 := &num
// 方式3:使用new函数
ptr3 := new(int)
*ptr3 = 20
2. 空指针检查
var ptr *int
if ptr == nil {
fmt.Println("指针为空")
}
// 安全访问
if ptr != nil {
fmt.Println(*ptr)
}
指针在函数中的应用
1. 传递指针参数
func modifyValue(ptr *int) {
*ptr = *ptr * 2
}
func main() {
value := 5
modifyValue(&value)
fmt.Println(value) // 10
}
2. 返回指针
func createPointer(x int) *int {
return &x
}
func main() {
ptr := createPointer(15)
fmt.Println(*ptr) // 15
}
结构体指针
type Person struct {
Name string
Age int
}
func main() {
// 创建结构体指针
p := &Person{Name: "Alice", Age: 25}
// 访问结构体字段
fmt.Println((*p).Name) // 传统方式
fmt.Println(p.Name) // Go语法糖,自动解引用
// 修改结构体字段
p.Age = 26
fmt.Println(p.Age) // 26
}
切片和映射的指针
func main() {
// 切片指针
slice := []int{1, 2, 3}
slicePtr := &slice
(*slicePtr)[0] = 10
// 映射指针
m := make(map[string]int)
mPtr := &m
(*mPtr)["key"] = 100
fmt.Println(slice) // [10 2 3]
fmt.Println(m) // map[key:100]
}
指针的注意事项
-
不要返回局部变量的地址
// 错误示例
func badPointer() *int {
x := 10
return &x // x在函数结束后会被销毁
}
-
指针比较
a, b := 10, 10
ptr1, ptr2 := &a, &b
fmt.Println(ptr1 == ptr2) // false,指向不同地址
fmt.Println(*ptr1 == *ptr2) // true,值相同
-
多级指针
var num int = 42
var ptr *int = &num
var pptr **int = &ptr
fmt.Println(**pptr) // 42
最佳实践
- 在需要修改函数外部变量时使用指针
- 对于大型结构体,传递指针比传递值更高效
- 避免不必要的指针使用,增加代码复杂度
- 始终检查指针是否为nil后再解引用
指针是Golang中重要的特性,合理使用可以提升程序性能和灵活性,但需要谨慎处理以避免空指针异常和内存安全问题。