Go语言指针的基本概念:
var p *int // 声明指针
p = &variable // 取地址
*p = 100 // 解引用(通过指针修改变量值)
指针作为函数参数:
package main
import "fmt"
// 用户结构体
type User struct {
ID int
Name string
Balance float64
}
// 值传递:不会修改原用户余额
func updateBalanceValue(user User, amount float64) {
user.Balance += amount
fmt.Printf("函数内余额: %.2f\n", user.Balance)
}
// 指针传递:会修改原用户余额
func updateBalancePointer(user *User, amount float64) {
user.Balance += amount
fmt.Printf("函数内余额: %.2f\n", user.Balance)
}
// 交换两个变量的值
func swap(a, b *int) {
*a, *b = *b, *a
}
func main() {
// 用户账户场景
user := User{
ID: 1,
Name: "张三",
Balance: 1000.00,
}
fmt.Println("=== 值传递测试 ===")
fmt.Printf("原余额: %.2f\n", user.Balance)
updateBalanceValue(user, 500)
fmt.Printf("函数外余额: %.2f\n", user.Balance) // 仍然是1000
fmt.Println("\n=== 指针传递测试 ===")
fmt.Printf("原余额: %.2f\n", user.Balance)
updateBalancePointer(&user, 500)
fmt.Printf("函数外余额: %.2f\n", user.Balance) // 变成1500
// 交换变量
x, y := 10, 20
fmt.Printf("交换前: x=%d, y=%d\n", x, y)
swap(&x, &y)
fmt.Printf("交换后: x=%d, y=%d\n", x, y)
// 指针数组:批量处理用户
users := []*User{
{ID: 1, Name: "用户1", Balance: 100},
{ID: 2, Name: "用户2", Balance: 200},
{ID: 3, Name: "用户3", Balance: 300},
}
// 批量充值
for _, u := range users {
u.Balance += 50 // 直接通过指针修改
}
for _, u := range users {
fmt.Printf("%s的新余额: %.2f\n", u.Name, u.Balance)
}
}
package main
import "fmt"
// 修改切片内容
func modifySlice(s []int) {
if len(s) > 0 {
s[0] = 999 // 切片本身是引用类型,不需要指针
}
}
// 修改切片本身(长度、容量)
func modifySlicePointer(s *[]int) {
*s = append(*s, 888) // 需要指针,因为可能重新分配内存
}
func main() {
// 切片是引用类型,但重新分配内存时需要指针
nums := []int{1, 2, 3}
fmt.Println("原切片:", nums)
modifySlice(nums)
fmt.Println("修改元素后:", nums)
modifySlicePointer(&nums)
fmt.Println("添加元素后:", nums)
}
package main
import "fmt"
// 二级指针:修改指针变量的值
func updatePointer(ptr *int, newValue int) {
*ptr = newValue
}
func main() {
x := 10
p := &x
fmt.Printf("x=%d, *p=%d\n", x, *p)
updatePointer(p, 20)
fmt.Printf("x=%d, *p=%d\n", x, *p)
// 指针的指针
pp := &p
fmt.Printf("p存储的地址: %p\n", p)
fmt.Printf("pp存储的地址: %p\n", *pp)
}
本课时我们学习了: