GO常量指针

Go语言中的常量使用关键字const定义,用于存储不会改变的数据,常量是在编译时被创建的,即使定义在函数内部也是如此,并且只能是布尔型、数字型(整数型、浮点型和复数)和字符串型。

由于编译时的限制,定义常量的表达式必须为能被编译器求值的常量表达式。

声明格式:

type可以省略

和变量声明一样,可以批量声明多个常量:

	const (e = 2.14pi=3.14)

所有常量的运算都可以在编译期完成,这样不仅可以减少运行时的工作,也方便其他代码的编译优化,当操作数是常量时,一些运行时的错误也可以在编译时被发现,例如整数除零、字符串索引越界、任何导致无效浮点数的操作等。

常量间的所有算术运算、逻辑运算和比较运算的结果也是常量,对常量的类型转换操作或以下函数调用都是返回常量结果:len、cap、real、imag、complex 和 unsafe.Sizeof。

因为它们的值是在编译期就确定的,因此常量可以是构成类型的一部分

如果是批量声明的常量,除了第一个外其它的常量右边的初始化表达式都可以省略,如果省略初始化表达式则表示使用前面常量的初始化表达式,对应的常量类型也是一样的。例如:

const (a = 1bc = 2d
)
fmt.Println(a, b, c, d) // "1 1 2 2"

1.1 iota 常量生成器

常量声明可以使用 iota 常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式。

在一个 const 声明语句中,在第一个声明的常量所在的行,iota 将会被置为 0,然后在每一个有常量声明的行加1

比如,定义星期日到星期六,从0-6

2. 指针

指针(pointer)在Go语言中可以被拆分为两个核心概念:

  • 类型指针,允许对这个指针类型的数据进行修改,传递数据可以直接使用指针,而无须拷贝数据,类型指针不能进行偏移和运算。
  • 切片,由指向起始元素的原始指针、元素数量和容量组成。

受益于这样的约束和拆分,Go语言的指针类型变量即拥有指针高效访问的特点,又不会发生指针偏移,从而避免了非法修改关键性数据的问题。

同时,垃圾回收也比较容易对不会发生偏移的指针进行检索和回收。

切片比原始指针具备更强大的特性,而且更为安全。

切片在发生越界时,运行时会报出宕机,并打出堆栈,而原始指针只会崩溃。

2.1 如何理解指针

var a int = 10

如果用大白话来解释上述语句:

在内存中开辟了一片空间,空间内存放着数值10,这片空间在整个内存当中,有一个唯一的地址,用来进行标识,指向这个地址的变量就称为指针

如果用类比的说明:

内存比作酒店,每个房间就是一块内存,上述代码表示为:定了一间房间a,让10住进了房间,房间有一个门牌号px,这个px就是房间的地址,房卡可以理解为就是指针,指向这个地址。

一个指针变量可以指向任何一个值的内存地址,它所指向的值的内存地址在 32 和 64 位机器上分别占用 4 或 8 个字节,占用字节的大小与所指向的值的大小无关。

当一个指针被定义后没有分配到任何变量时,它的默认值为 nil。

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。

Go语言中使用在变量名前面添加&操作符(前缀)来获取变量的内存地址(取地址操作),格式如下:

//其中 v 代表被取地址的变量,变量 v 的地址使用变量 ptr 进行接收,ptr 的类型为*T,称做 T 的指针类型,*代表指针。
ptr := &v    // v 的类型为 T

	var cat int = 1var str string = "hahah"fmt.Printf("%p %p", &cat, &str)  //0xc00000a0d8 0xc000020070

变量、指针和地址三者的关系是,每个变量都拥有地址,指针的值就是地址

当使用&操作符对普通变量进行取地址操作并得到变量的指针后,可以对指针使用*操作符,也就是指针取值

	var room int = 10ptr := &roomfmt.Println(ptr)        //0xc000096068fmt.Printf("%T\n", ptr) //*intfmt.Println(*ptr)  //10

取地址操作符&和取值操作符*是一对互补操作符,&取出地址,*根据地址取出地址指向的值

变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

  • 对变量进行取地址操作使用&操作符,可以获得这个变量的指针变量。
  • 指针变量的值是指针地址。
  • 对指针变量进行取值操作使用*操作符,可以获得指针变量指向的原变量的值。

2.3 创建指针的另一种方法

Go语言还提供了另外一种方法来创建指针变量,格式如下:

new(类型)

str := new(string)
*str = "码神之路Go语言教程"
fmt.Println(*str)

new() 函数可以创建一个对应类型的指针,创建过程会分配内存,被创建的指针指向默认值。

2.4 指针小案例

获取命令行的输入信息

Go语言内置的 flag 包实现了对命令行参数的解析,flag 包使得开发命令行工具更为简单。

3. 变量的生命周期

变量的生命周期指的是在程序运行期间变量有效存在的时间间隔。

变量的生命周期与变量的作用域有不可分割的联系:

  1. 全局变量:它的生命周期和整个程序的运行周期是一致的;
  2. 局部变量:它的生命周期则是动态的,从创建这个变量的声明语句开始,到这个变量不再被引用为止;
  3. 形式参数和函数返回值:它们都属于局部变量,在函数被调用的时候创建,函数调用结束后被销毁。

go的内存中应用了两种数据结构用于存放变量:

  1. 堆(heap):堆是用于存放进程执行中被动态分配的内存段。它的大小并不固定,可动态扩张或缩减。当进程调用 malloc 等函数分配内存时,新分配的内存就被动态加入到堆上(堆被扩张)。当利用 free 等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减);
  2. 栈(stack):栈又称堆栈, 用来存放程序暂时创建的局部变量,也就是我们函数的大括号{ }中定义的局部变量。

栈是先进后出,往栈中放元素的过程,称为入栈,取元素的过程称为出栈。

栈可用于内存分配,栈的分配和回收速度非常快

在程序的编译阶段,编译器会根据实际情况自动选择在栈或者堆上分配局部变量的存储空间,不论使用 var 还是 new 关键字声明变量都不会影响编译器的选择。

func f() {x := 10global = &x
}func g() {y := new(int)*y = 1
}

上述代码中,函数 f 里的变量 x 必须在堆上分配,因为它在函数退出后依然可以通过包一级的 global 变量找到,虽然它是在函数内部定义的。

用Go语言的术语说,这个局部变量 x 从函数 f 中逃逸了。

相反,当函数 g 返回时,变量 y 不再被使用,也就是说可以马上被回收的。因此,y 并没有从函数 g 中逃逸,编译器可以选择在栈上分配 *y 的存储空间,也可以选择在堆上分配,然后由Go语言的 GC(垃圾回收机制)回收这个变量的内存空间。

4. 类型别名

类型别名是 Go 1.9 版本添加的新功能,主要用于解决代码升级、迁移中存在的类型兼容性问题。

格式:

//TypeAlias 只是 Type 的别名,本质上 TypeAlias 与 Type 是同一个类型,就像一个孩子小时候有小名、乳名,上学后用学名,英语老师又会给他起英文名,但这些名字都指的是他本人。
type TypeAlias = Type

还有一种是类型定义:

//定义Name为Type类型 ,定义之后 Name为一种新的类型
type Name Type

类型别名与类型定义表面上看只有一个等号的差异,那么它们之间实际的区别有哪些呢?

	//将newInt定义为int类型type newInt int//将int取一个别名叫intAlicetype intAlice = intvar a newIntfmt.Printf("%T\n", a) //main.newIntvar b intAlice   //IntAlias 类型只会在代码中存在,编译完成时,不会有 IntAlias 类型。fmt.Printf("%T\n", b) //int


8. 字符串与其他数据类型的转换

整数 与 字符串

	var str1 string = "1"//字符串转整型res, _ := strconv.Atoi(str1)fmt.Printf("%T\n", res)//整型转字符串myString := strconv.Itoa(res)fmt.Printf("%T", myString)

浮点数 与字符串

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/714179.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化测试系列 —— UI自动化测试!

UI 测试是一种测试类型,也称为用户界面测试,通过该测试,我们检查应用程序的界面是否工作正常或是否存在任何妨碍用户行为且不符合书面规格的 BUG。了解用户将如何在用户和网站之间进行交互以执行 UI 测试至关重要,通过执行 UI 测试…

Maven 插件之 maven-enforcer-plugin 解决冲突重复依赖

目录 0、前言1、enforcer 是什么2、能干什么3、怎么用4、规则5、扩展规则6、使用7、banDuplicateClasses8、banDuplicatePomDependencyVersions 0、前言 maven 项目种经常出现 jar 包冲突、重复依赖、无效引用怎么办,maven-enforcer-plugin 了解一下 1、enforcer …

《AI纪元:幻域探险》

游戏项目名称:《AI纪元:幻域探险》 游戏类型:AI驱动的角色扮演探险游戏(RPG) 背景设定: 《AI纪元:幻域探险》设定在一个名为“幻域”的广阔虚拟世界。这个世界由高度发达的AI技术支持&#xff0…

SpringCloud-同步异步通讯比较

本文详细探讨了同步通讯和异步通讯在信息传递中的区别,以及它们分别带来的优势和不足。通过对支付流程的案例分析,突显了同步通讯可能面临的阻塞和服务依赖问题,而异步通讯通过引入事件驱动模式和消息代理(Broker)成功…

SQL Server 开发环境配置教程(SSMS+SQL Prompt)

背景 记录一下 SQL Server 常用开发软件 体验了各种数据库IDE(DBeaver、Navicat、DataGrip)之后综合下来还是感觉 SSMSSQL Prompt 对于 SQL Server 最好用,所以在此记录一下配置过程 数据库可视化管理工具SSMS 官方下载地址: https://learn.microsoft…

Java基础数据结构之栈

一.什么是栈 栈是一种特殊的线性表,它只允许在固定的一端进行元素的添加与使用,且遵循先进后出的原则。添加取用元素的一端称为栈顶,另一端称为栈底。出栈和入栈都是操作栈顶元素 二.栈的模拟实现 栈的底层是一个数组 这是里面的成员变量以…

智能汽车加速车规级存储应用DS2431P+TR 汽车级EEPROM 存储器IC

DS2431PT&R是一款1024位1-Wire EEPROM芯片,由四页存储区组成,每页256位。数据先被写入一个8字节暂存器中,经校验后复制到EEPROM存储器。该器件的特点是,四页存储区相互独立,可以单独进行写保护或进入EPROM仿真模式…

第2章 线性代数

目录 1. 标量、向量、矩阵和张量2. 矩阵和向量相乘3. 单位矩阵和逆矩阵4. 线性相关和生成子空间5. 范数6. 特殊类型的矩阵和向量7. 特征分解8. 奇异值分解9. Moore-Penrose伪逆10. 迹运算11. 行列式 1. 标量、向量、矩阵和张量 标量(scalar):…

【 C++ 】特殊类设计

1、请设计一个类,不能被拷贝 拷贝只会出现在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。在C98和C11都有相对应的方法来解决此问题&#xff0c…

ssm172旅行社管理系统的设计与实现

** 🍅点赞收藏关注 → 私信领取本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅** 一 、设计说明 1.1 研究…

day03-Vue-Element

一、Ajax 1 Ajax 介绍 1.1 Ajax 概述 概念:Asynchronous JavaScript And XML,异步 的 JavaScript 和 XML。 作用: 数据交换:通过 Ajax 可以给服务器发送请求,并获取服务器响应的数据。异步交互:可以在 不…

Java教程:SpringBoot项目如何对接Nacos实现服务发现治理,配置管理

–Nacos大家都知道,不懂的可以去官网或者网上查阅一下,本次给大家讲解一下如何在SpringBoot项目中引入Nacos服务来进行服务治理与发现,配置管理等,在微服务当中是必不可少的,各个模块之间可以通过Feign远程调用&#x…

物联网主机:为智能交通赋能

物联网(IoT)技术的发展为智能交通领域带来了许多创新的解决方案。而在物联网应用中,物联网主机起着关键的作用。本文将为大家介绍一款名为E6000的物联网主机,它是一种多协议、多接口的物联网主机,为智能交通系统的建设…

antvX6 - Vue自定义节点,并实现多种画布操作,拖拽、缩放、连线、双击、检索等等

一、 首先 antv x6 分为两个版本 低版本和高版本 我这里是使用的2.0版本 并且搭配了相关插件 例如:画布的图形变换、地图等 个人推荐 2.0版本,高版本配置多,可使用相关插件多,但是文档描述小,仍在更新, 低…

小d和图片压缩

题目描述 小ddd和她对象小红去海洋馆玩了,但是由于小ddd拍照技术不好,他对象说把她拍的像嘎子! 小ddd看了看,发现是小红最近长痘痘了,于是他为了讨小红开心,让痘痘看不见,自学了图像压缩这个技…

装饰器模式 详解 设计模式

装饰器模式 它允许你在不改变对象结构的情况下,动态地将新功能附加到对象上。 结构: 抽象组件(Component):定义了原始对象和装饰器对象的公共接口或抽象类,可以是具体组件类的父类或接口。具体组件&…

固定排班计划

目录 1.按发车时间排序。 2.排班日期默认当天时间。 3.编辑不可修改线路和排班日期。 4.线路、车号、司机是否匹配,不匹配不可入库(和其他表比),线路、发车时间、司机、车号、日期、上下行相同不可入库(和自己表比…

GO语言学习笔记(与Java的比较学习)(一)

GO的优缺点: 此处引用华为云开发者联盟的一篇文章: GO语言的亮点很明显: GoDoc。 GoDoc的静态语言分析能力很强大,可以直接从代码和注释生成漂亮的文档。这一点区别于其他的类似工具如JavaDoc, PHPDoc或者JSDoc。这些工具需要添加…

如何在群晖Docker运行本地聊天机器人并结合内网穿透发布到公网访问

文章目录 1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 随着ChatGPT 和open Sora 的热度剧增,大语言模型时代,开启了AI新篇章,大语言模型的应用非常广泛,包括聊天机…

C# Socket通信从入门到精通(21)——TCP发送文件与接收文件 C#代码实现

1、前言 我们在开发上位机软件的过程中经常需要发送文件,本文就是介绍如何利用tcp客户端发送文件、tcp服务器端接收文件,而且本文介绍的方法可以自动发送一个文件夹下的所有子目录以及所有文件,经验来自于实际项目,具备非常有价值的参考意义! 2、发送文件以及C#代码 被发…