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()
}
相关推荐
孙严Pay几秒前
网关支付:在线交易的安全核心枢纽
笔记·科技·计算机网络·其他·微信
代码游侠2 分钟前
应用——Linux Framebuffer 图形库显示
linux·运维·服务器·数据库·笔记·算法
m0_626535203 分钟前
下班之后学习一会儿英语
学习
laplace01238 分钟前
Part 1. 大模型RAG入门基础架构介绍
笔记·语言模型·langchain·rag
【上下求索】8 分钟前
学习笔记097——Ubuntu系统中如何通过service服务的方式启动 jar 包?
java·笔记·学习·ubuntu
Nan_Shu_61412 分钟前
学习:Redis (1)
数据库·redis·学习
智慧化智能化数字化方案13 分钟前
【精品资料鉴赏】财务数智化智能化建设学习
人工智能·学习·财务数字化·财务数智化·财务一体化·财务共享平台·财务成熟度评估模型
烟囱土著23 分钟前
捣鼓15天,我写了一个拼音发音点读小程序
学习·微信·微信小程序·小程序·拼音
_Kayo_30 分钟前
node.js 学习笔记5
笔记·学习
报错小能手34 分钟前
线程池学习(四)实现缓存线程池(Cached ThreadPool)
java·学习·缓存