Golang学习笔记_11——指针

Golang学习笔记_08------For循环
Golang学习笔记_09------if条件判断
Golang学习笔记_10------Switch


文章目录

    • 指针
      • [1. 定义](#1. 定义)
      • [2. 初始化](#2. 初始化)
      • [3. 解引用指针](#3. 解引用指针)
      • [4. 指针的传递](#4. 指针的传递)
      • [5. 指针的零值](#5. 指针的零值)
      • [6. 指针的比较](#6. 指针的比较)
      • [7. 其他(可选)](#7. 其他(可选))
    • 源码

指针

在Go语言中,指针是一种非常基本且重要的数据类型,它允许你直接访问和操作内存地址。指针的使用在C和C++等语言中非常普遍,但Go语言在提供指针功能的同时,也尽量简化了其复杂性,使得指针在Go中相对安全且易于使用。

1. 定义

指针是一个存储了内存地址的变量。在Go中,你可以通过 *Type 来声明一个指针,其中 Type 是指针指向的变量的类型。例如,*int 是一个指向 int 类型变量的指针。

go 复制代码
var p *int

2. 初始化

你可以将变量的地址赋值给指针。使用 & 操作符来获取变量的内存地址。

go 复制代码
var a int = 42
var p *int &a

3. 解引用指针

解引用(或称取消引用)指针意味着访问指针所指向的内存位置的值。在Go中,这是通过前置星号*完成的。

go 复制代码
fmt.Println(*p) // 打印 p 指向的值,即 x 的值
*p = 21         // 修改 p 指向的值,即修改 x 的值

4. 指针的传递

在函数调用时,如果你希望函数能够修改调用者的变量,你可以将变量的指针传递给函数。

go 复制代码
func modifyValue(p *int) {
	*p = 100
}

测试方法

go 复制代码
func Test_modifyValue(t *testing.T) {
	num := 40

	type args struct {
		p *int
	}
	tests := []struct {
		name string
		args args
	}{
		{
			name: "init value = 1",
			args: args{&num},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			modifyValue(tt.args.p)
			fmt.Println("modify value = ", num)
		})
	}
}

输出结果

go 复制代码
=== RUN   Test_modifyValue
=== RUN   Test_modifyValue/init_value_=_1
modify value =  100
--- PASS: Test_modifyValue (0.00s)
    --- PASS: Test_modifyValue/init_value_=_1 (0.00s)
PASS

5. 指针的零值

未初始化的指针的默认值是 nil。尝试解引用一个 nil 指针会导致运行时错误(panic)。

go 复制代码
var p *int
fmt.Println(*p) 
// 这将导致运行时错误: invalid memory address or nil pointer dereference

6. 指针的比较

go 复制代码
var a int = 42
var b int = 42
var p1 *int = &a
var p2 *int = &b
var p3 *int = &a

fmt.Println(p1 == p2) // 输出: false
fmt.Println(p1 == p3) // 输出: true

测试方法

go 复制代码
func Test_comparePoint(t *testing.T) {
	comparePoint()
}

输出结果

复制代码
=== RUN   Test_comparePoint
false
true
--- PASS: Test_comparePoint (0.00s)
PASS

7. 其他(可选)

指针在数组、切面和结构体中会有重要作用。

go 复制代码
// 指针数组
var ptrArray []*int
ptrArray = append(ptrArray, &a, &b)
fmt.Println(*ptrArray[0], *ptrArray[1]) // 输出: 42 42(假设a和b的初始值都是42)

// 指针切片
var ptrSlice []*int
ptrSlice = make([]*int, 2)
ptrSlice[0] = &a
ptrSlice[1] = &b
fmt.Println(*ptrSlice[0], *ptrSlice[1]) // 输出: 42 42(假设a和b的初始值都是42)

type Rectangle struct {
    Width, Height int
}

func (r *Rectangle) Area() int {
    return r.Width * r.Height
}

func (r *Rectangle) SetWidth(width int) {
    r.Width = width
}

func main() {
    rect := Rectangle{Width: 10, Height: 5}
    fmt.Println(rect.Area()) // 输出: 50
    rect.SetWidth(20)
    fmt.Println(rect.Area()) // 输出: 100
}

源码

go 复制代码
// point_demo.go 文件
package point_demo

import "fmt"

func modifyValue(p *int) {
	*p = 100
}

func comparePoint() {
	var a int = 42
	var b int = 42
	var p1 *int = &a
	var p2 *int = &b
	var p3 *int = &a

	fmt.Println(p1 == p2) // 输出: false
	fmt.Println(p1 == p3) // 输出: true
}
go 复制代码
// point_demo_test.go 文件
package point_demo

import (
	"fmt"
	"testing"
)

func Test_modifyValue(t *testing.T) {
	num := 40

	type args struct {
		p *int
	}
	tests := []struct {
		name string
		args args
	}{
		{
			name: "init value = 1",
			args: args{&num},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			modifyValue(tt.args.p)
			fmt.Println("modify value = ", num)
		})
	}
}

func Test_comparePoint(t *testing.T) {
	comparePoint()
}
相关推荐
绘梨衣5471 分钟前
异步任务队列-学习2
爬虫·python·学习·任务队列
摇滚侠39 分钟前
《SpringBoot 3:入门与应用实战》第 9 章 使用 WebMvc 开发应用 阅读笔记 1
spring boot·笔记·后端
程序员小八7771 小时前
Go 语言特性
开发语言·后端·golang
喜欢吃燃面1 小时前
HTTP协议深度解析:从请求响应到状态管理与安全传输
linux·网络协议·学习
我命由我123451 小时前
财务学习 - 权责发生制(应收应付制)
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·学习方法
MartinYeung52 小时前
[论文学习]小型代码语言模型中的潜伏代理行为研究
学习·语言模型·php
MartinYeung52 小时前
[论文学习]MPIB:医疗提示注入基准——针对LLM临床安全性的系统性评估
人工智能·python·学习
MartinYeung52 小时前
[论文学习]医学AI安全风险分类:S1-S4分级框架深度分析
人工智能·学习·安全
优化Henry2 小时前
5G站点BBU功能模块集成化与偶发案例
运维·网络·学习·5g·tdd
丰锋ff3 小时前
设计模式学习笔记
笔记·学习·设计模式