深入探索Go语言中的指针:内存操作的艺术

2024-09-04 03:36

本文主要是介绍深入探索Go语言中的指针:内存操作的艺术,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,尽管指针(pointer)和switch语句在概念上并无直接联系,但本文将它们并置讨论的原因在于:这两个编程概念在实际学习和应用过程中常被编程人员所忽视。

  1. 对于指针的使用,初学者往往因其概念的抽象性和操作的复杂性而产生畏惧,倾向于避免使用或在并发编程中错误地应用,这可能导致严重的数据竞争和同步问题,影响程序的稳定性和安全性。
  2. 另一方面,许多开发者在面对条件分支时,习惯性地依赖if-else语句,而未能充分利用switch语句在处理多条件逻辑时的高效性和清晰性,从而错失了优化代码结构和提升程序性能的机会。

指针pointer

在Go语言中,指针是编程中一个核心的概念,它允许程序直接操作内存地址。虽然Go语言对指针的操作相对简单,主要通过两个符号来实现:

  1. & 操作符用于获取变量的内存地址。当你想要获取一个变量的引用,而不是它的值时,可以使用&来取地址。
  2. * 操作符用于间接引用,也就是通过一个指针来访问和修改它所指向的内存地址上存储的值。

应用

在许多编程语言中,变量是对内存中存储的值的一个命名引用。然而,有时我们可能需要直接操作内存地址,这就需要用到指针。Go语言提供了两种基本的指针操作符号:&用于获取变量的内存地址,而*用于间接引用,即通过指针来访问或修改内存地址上存储的值。

现在,让我们通过一个具体的例子来演示这些操作:

n := 18
// 取地址
fmt.Println(&n)
fmt.Println(*&n)

打印结果如下:

在这里插入图片描述

查询内存地址的类型

当我们获取一个变量的地址时,实际上是创建了一个指针类型的变量,这个指针变量的类型是由它所指向的变量的类型决定的。例如,如果一个指针指向一个int类型的变量,那么这个指针的类型就是*int,即指向int的指针。

现在,让我们通过代码示例来演示如何查询内存地址的类型,并根据这个地址来获取和打印原始变量的值:

p := &n
// 根据地址取值
fmt.Printf("%T\n", p) // 打印结果是*int,即int类型的指针
m := *p
fmt.Println(m) //根据地址取值

打印结果如下:

在这里插入图片描述

我们发现打印的结果是:*int,即int类型的指针。

nil pointer

nil是一个特殊的值,表示指针没有指向任何内存地址。这与C或C++中的空指针概念类似,但Go语言的nil指针更加安全,因为它们不允许进行解引用操作,从而避免了潜在的程序崩溃。当一个指针变量被声明后未初始化,它就是一个nil指针。了解如何声明和识别nil指针,以及如何安全地使用它们,是每个Go程序员的必备技能。

现在,让我们通过代码示例来演示nil指针的使用和转换:

var a1 *int     //nil pointer
fmt.Println(a1) //<nil>var a2 = new(int)
fmt.Println(a2)  //内存地址 0xc000108010
fmt.Println(*a2) //0 根据内存地址取值 没有值返回0*a2 = 100        //根据内存地址赋值
fmt.Println(*a2) //100

打印结果如下:

在这里插入图片描述

总结如下:

在这里插入图片描述

  1. 对变量进行取地址操作(&),可以获得这个变量的指针变量;
  2. 指针变量的值是指针地址(内存地址);
  3. 对指针变量进行取值操作(*),可以获得这个指针变量指向原变量的值,即通过内存地址取值。

switch

我们往往习惯于使用if判断,switch可以简化if判断。

switch的作用和if是一样的,都是进行条件判断,引入switch的原因是能简化我们的if判断,让代码的可读性更强。

可读性更好

举个例子:if判断来判断手指的名称。

finger :=2
if finger==1 {fmt.Println("大拇指")
}else if finger==2 {fmt.Println("食指")
}else if finger==5 {fmt.Println("小拇指")
}else {fmt.Println("无效")
}

switch判断手指名称:

finger := 2
switch finger {
case 1:fmt.Println("大拇指")
case 2:fmt.Println("食指")
case 5:fmt.Println("小拇指")
default:fmt.Println("无效")
}

对比之下立竿剪影:switch case 这种方式可读性更好。

case后支持多个参数

举个例子:奇偶数判断。

switch n := 3; n {
case 1, 3, 5, 7, 9:fmt.Println("奇数")
case 2, 4, 6, 8, 10:fmt.Println("偶数")
}

case后加判断

举个例子:

age := 29
switch {
case age < 18:fmt.Println("好好学习Z")
case age > 18 && age < 60:fmt.Println("好好上班")
case age > 60:fmt.Println("希望不用继续上班了,哈哈")
default:fmt.Println(age)
}

注意:当在case后加判断时,switch后面不需要传入参数,否则会报错:类型不匹配。

在这里插入图片描述

fallthrough

在一个 switch 块内,每个 case 无需声明 break 来终止,如果想顺序执行使用 fallthrough;在一个switch块内,都必须包含一个 default 语句并且放在最后,即使它什么代码也没有。

package mainimport "fmt"func main() {switch {case false:fmt.Println("false1")fallthroughcase true:fmt.Println("true1")fallthroughcase false:fmt.Println("false2")fallthroughcase true:fmt.Println("true2")case false:fmt.Println("false3")fallthroughdefault:fmt.Println("default case")}
}

总结

相信你阅读完这篇文章对Go语言中的指针有了更深刻的理解。至于switch,只要我们心里有这个概念即可:switch作用和if一样,当我们意识到需要写多个if判断时,改用switch实现,往往会是比较好的实践。

这篇关于深入探索Go语言中的指针:内存操作的艺术的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1134886

相关文章

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

使用Java填充Word模板的操作指南

《使用Java填充Word模板的操作指南》本文介绍了Java填充Word模板的实现方法,包括文本、列表和复选框的填充,首先通过Word域功能设置模板变量,然后使用poi-tl、aspose-words... 目录前言一、设置word模板普通字段列表字段复选框二、代码1. 引入POM2. 模板放入项目3.代码

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

Rust 智能指针的使用详解

《Rust智能指针的使用详解》Rust智能指针是内存管理核心工具,本文就来详细的介绍一下Rust智能指针(Box、Rc、RefCell、Arc、Mutex、RwLock、Weak)的原理与使用场景,... 目录一、www.chinasem.cnRust 智能指针详解1、Box<T>:堆内存分配2、Rc<T>:

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块

Java 字符串操作之contains 和 substring 方法最佳实践与常见问题

《Java字符串操作之contains和substring方法最佳实践与常见问题》本文给大家详细介绍Java字符串操作之contains和substring方法最佳实践与常见问题,本文结合实例... 目录一、contains 方法详解1. 方法定义与语法2. 底层实现原理3. 使用示例4. 注意事项二、su

使用Go调用第三方API的方法详解

《使用Go调用第三方API的方法详解》在现代应用开发中,调用第三方API是非常常见的场景,比如获取天气预报、翻译文本、发送短信等,Go作为一门高效并发的编程语言,拥有强大的标准库和丰富的第三方库,可以... 目录引言一、准备工作二、案例1:调用天气查询 API1. 注册并获取 API Key2. 代码实现3