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()
}
相关推荐
爱意随风起风止意难平13 分钟前
003 flutter初始文件讲解(2)
学习·flutter
东京老树根15 分钟前
SAP学习笔记 - 开发18 - 前端Fiori开发 应用描述符(manifest.json)的用途
笔记·学习
虾球xz36 分钟前
CppCon 2014 学习:C++ Memory Model Meets High-Update-Rate Data Structures
java·开发语言·c++·学习
m0_6786933339 分钟前
深度学习笔记25-RNN心脏病预测(Pytorch)
笔记·rnn·深度学习
水水沝淼㵘44 分钟前
嵌入式开发学习日志(linux系统编程--系统编程之 进程间通信IPC)Day32
linux·运维·学习
我的golang之路果然有问题1 小时前
快速了解GO+ElasticSearch
开发语言·经验分享·笔记·后端·elasticsearch·golang
凤年徐1 小时前
【数据结构初阶】顺序表的应用
c语言·开发语言·数据结构·c++·笔记·算法·顺序表
在成都搬砖的鸭鸭2 小时前
【Golang】使用gin框架导出excel和csv文件
golang·excel·gin
Lu Yao_2 小时前
golang -- slice 底层逻辑
golang