《Go 语言第一课》课程学习笔记(八)

基本数据类型

Go 原生支持的数值类型有哪些?

  • Go 语言的类型大体可分为基本数据类型、复合数据类型和接口类型这三种。
    • 其中,我们日常 Go 编码中使用最多的就是基本数据类型,而基本数据类型中使用占比最大的又是数值类型。

整型

  • Go 语言的整型,主要用来表示现实世界中整型数量等。它可以分为平台无关整型和平台相关整型这两种,它们的区别主要就在,这些整数类型在不同 CPU 架构或操作系统下面,它们的长度是否是一致的。
    • 平台无关整型
      • 它们在任何 CPU 架构或任何操作系统下面,长度都是固定不变的。
        在这里插入图片描述
      • 有符号整型(int8-int64)和无符号整型(uint8-uint64)的本质差别在于最高二进制位(bit 位)是否被解释为符号位,这点会影响到无符号整型与有符号整型的取值范围。
      • Go 采用 2 的补码(Two’s Complement)作为整型的比特位编码方法。因此,我们不能简单地将最高比特位看成负号,把其余比特位表示的值看成负号后面的数值。Go 的补码是通过原码逐位取反后再加 1 得到的。
    • 平台相关整型
      • 与平台无关整型对应的就是平台相关整型,它们的长度会根据运行平台的改变而改变。
      • Go 语言原生提供了三个平台相关整型,它们是 int、uint 与 uintptr。
        在这里插入图片描述
      • 由于这三个类型的长度是平台相关的,所以我们在编写有移植性要求的代码时,千万不要强依赖这些类型的长度。
      • 如果不知道这三个类型在目标运行平台上的长度,可以通过 unsafe 包提供的 SizeOf 函数来获取。
  • 整型的溢出问题
    • 如果这个整型因为参与某个运算,导致结果超出了这个整型的值边界,我们就说发生了整型溢出的问题。
    • 由于整型无法表示它溢出后的那个“结果”,所以出现溢出情况后,对应的整型变量的值依然会落到它的取值范围内,只是结果值与我们的预期不符,导致程序逻辑出错。
  • 字面值与格式化输出
    • Go 语言在设计开始,就继承了 C 语言关于数值字面值(Number Literal)的语法形式。
    • 早期 Go 版本支持十进制、八进制、十六进制的数值字面值形式。
    • Go 1.13 版本中,Go 又增加了对二进制字面值的支持和两种八进制字面值的形式。
    • 为提升字面值的可读性,Go 1.13 版本还支持在字面值中增加数字分隔符“_”,分隔符可以用来将数字分组以提高可读性。
    • 反过来,我们也可以通过标准库 fmt 包的格式化输出函数,将一个整型变量输出为不同进制的形式。

浮点型

  • 浮点型的二进制表示
    • Go 语言提供了 float32 与 float64 两种浮点类型,它们分别对应单精度与双精度浮点数值类型。
      • 不过,Go 语言中没有提供 float 类型
      • 换句话说,Go 提供的浮点类型都是平台无关的。
      • 无论是 float32 还是 float64,它们的变量的默认值都为 0.0,不同的是它们占用的内存空间大小是不一样的,可以表示的浮点数的范围与精度也不同。
    • 浮点数在内存中的二进制表示(Bit Representation)要比整型复杂得多:在这里插入图片描述
      • 浮点数在内存中的二进制表示分三个部分:符号位、阶码(即经过换算的指数),以及尾数。这样表示的一个浮点数,它的值等于: ( − 1 ) s ∗ 1. M ∗ 2 E − o f f s e t (-1)^s * 1.M * 2 ^{E-offset} (1)s1.M2Eoffset
        • 当符号位为 1 时,浮点值为负值;
        • 当符号位为 0 时,浮点值为正值。
        • 公式中 offset 被称为阶码偏移值。
      • 单精度(float32)与双精度(float64)浮点数在阶码和尾数上的不同:
        在这里插入图片描述
        • 单精度浮点类型(float32)为符号位分配了 1 个 bit,为阶码分配了 8 个 bit,剩下的 23 个 bit 分给了尾数。
        • 而双精度浮点类型,除了符号位的长度与单精度一样之外,其余两个部分的长度都要远大于单精度浮点型,阶码可用的 bit 位数量为 11,尾数则更是拥有了 52 个 bit 位。
  • 字面值与格式化输出
    • Go 浮点类型字面值大体可分为两类,一类是直白地用十进制表示的浮点值形式。这一类,我们通过字面值就可直接确定它的浮点值。
    • 另一类则是科学计数法形式。采用科学计数法表示的浮点字面值,我们需要通过一定的换算才能确定其浮点值。而且在这里,科学计数法形式又分为十进制形式表示的,和十六进制形式表示的两种。
      6674.28e-2 // 6674.28 * 10^(-2) = 66.742800
      .12345E+5 // 0.12345 * 10^5 = 12345.000000
      0x2.p10 // 2.0 * 2^10 = 2048.000000
      0x1.Fp+0 // 1.9375 * 2^0 = 1.937500
      

复数类型

  • Go 提供两种复数类型,它们分别是 complex64 和 complex128,complex64 的实部与虚部都是 float32 类型,而 complex128 的实部与虚部都是 float64 类型。如果一个复数没有显示赋予类型,那么它的默认类型为 complex128。
  • 关于复数字面值的表示,我们其实有三种方法:
    • 第一种,我们可以通过复数字面值直接初始化一个复数类型变量:var c = 5 + 6i
    • 第二种,Go 还提供了 complex 函数,方便我们创建一个 complex128 类型值:var c = complex(5, 6) // 5 + 6i
    • 第三种,你还可以通过 Go 提供的预定义的函数 real 和 imag,来获取一个复数的实部与虚部,返回值为一个浮点类型:
      var c = complex(5, 6) // 5 + 6i
      r := real(c) // 5.000000
      i := imag(c) // 6.000000
      

字符串类型

  • 在 Go 中,字符串类型为 string。
    • Go 语言通过 string 类型统一了对“字符串”的抽象。
    • 这样无论是字符串常量、字符串变量或是代码中出现的字符串字面值,它们的类型都被统一设置为 string。
    • string 类型的数据是不可变的,提高了字符串的并发安全性和存储利用率。
  • Go 字符串的组成
    • Go 语言中的字符串值也是一个可空的字节序列,字节序列中的字节个数称为该字符串的长度。一个个的字节只是孤立数据,不表意。
    • 字符串是由一个可空的字符序列构成。
  • rune 类型与字符字面值
    • Go 使用 rune 这个类型来表示一个 Unicode 码点。rune 本质上是 int32 类型的别名类型,它与 int32 类型是完全等价的。
    • 一个 rune 实例就是一个 Unicode 字符,一个 Go 字符串也可以被视为 rune 实例的集合。我们可以通过字符字面值来初始化一个 rune 变量。
    • 在 Go 中,字符字面值有多种表示法,最常见的是通过单引号括起的字符字面值。
    • 我们还可以使用 Unicode 专用的转义字符\u 或\U 作为前缀,来表示一个 Unicode 字符。
    • 由于表示码点的 rune 本质上就是一个整型数,所以我们还可用整型值来直接作为字符字面值给 rune 变量赋值。
  • 字符串字面值
    • 字符串是字符的集合,我们需要把表示单个字符的单引号,换为表示多个字符组成的字符串的双引号。
    • string 类型其实是一个“描述符”,它本身并不真正存储字符串数据,而仅是由一个指向底层存储的指针和字符串的长度字段组成的。
    • 我们直接将 string 类型通过函数 / 方法参数传入也不会带来太多的开销。因为传入的仅仅是一个“描述符”,而不是真正的字符串数据。
  • Go 字符串类型的常见操作
    • 下标
      • 在字符串的实现中,真正存储数据的是底层的数组。
      • 字符串的下标操作本质上等价于底层数组的下标操作。
        var s = "中国人"
        fmt.Printf("0x%x\n", s[0]) // 0xe4:字符“中” utf-8编码的第一个字节
        
      • 通过下标操作,我们获取的是字符串中特定下标上的字节,而不是字符。
    • 字符迭代
      • Go 有两种迭代形式:常规 for 迭代与 for range 迭代。
      • 通过这两种形式的迭代对字符串进行操作得到的结果是不同的。
      • 通过常规 for 迭代对字符串进行的操作是一种字节视角的迭代,每轮迭代得到的的结果都是组成字符串内容的一个字节,以及该字节所在的下标值,这也等价于对字符串底层数组的迭代。
      • 通过 for range 迭代,我们每轮迭代得到的是字符串中 Unicode 字符的码点值,以及该字符在字符串中的偏移值。
      • 我们可以通过这样的迭代,获取字符串中的字符个数,而通过 Go 提供的内置函数 len,我们只能获取字符串内容的长度(字节个数)。
      • 获取字符串中字符个数更专业的方法,是调用标准库 UTF-8 包中的 RuneCountInString 函数。
    • 字符串连接
      • Go 原生支持通过 +/+= 操作符进行字符串连接。
      • 虽然通过 +/+= 进行字符串连接的开发体验是最好的,但连接性能就未必是最快的了。
      • 除了这个方法外,Go 还提供了 strings.Builder、strings.Join、fmt.Sprintf 等函数来进行字符串连接操作
    • 字符串比较
      • Go 字符串类型支持各种比较关系操作符,包括 = =、!= 、>=、<=、> 和 <。
      • 在字符串的比较上,Go 采用字典序的比较策略,分别从每个字符串的起始处,开始逐个字节地对两个字符串类型变量进行比较。
        • 当两个字符串之间出现了第一个不相同的元素,比较就结束了,这两个元素的比较结果就会做为串最终的比较结果。
        • 如果出现两个字符串长度不同的情况,长度比较小的字符串会用空元素补齐,空元素比其他非空元素都小。
      • 鉴于 Go string 类型是不可变的,所以说如果两个字符串的长度不相同,那么我们不需要比较具体字符串数据,也可以断定两个字符串是不同的。但是如果两个字符串长度相同,就要进一步判断,数据指针是否指向同一块底层存储数据。如果还相同,那么我们可以说两个字符串是等价的,如果不同,那就还需要进一步去比对实际的数据内容。
    • 字符串转换
      • Go 支持字符串与字节切片、字符串与 rune 切片的双向转换,并且这种转换无需调用任何函数,只需使用显式类型转换就可以了。

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

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

相关文章

无涯教程-Perl - use函数

描述 此函数将MODULE导出的所有功能(或仅LIST引用的功能)导入当前包的名称空间。有效等效于- BEGIN { require "Module.pm"; Module->import(); }也用于在当前脚本上强加编译器指令(编译指示),尽管从本质上讲它们只是模块。 请注意,use语句在编译时进行判断。在…

高忆管理:药店零售概念回落,开开实业走低,此前7日大涨超80%

药店零售概念18日盘中大幅下挫&#xff0c;到发稿&#xff0c;华人健康跌逾11%&#xff0c;漱玉布衣、塞力医疗跌超9%&#xff0c;重药控股、浙江震元、榜首医药等跌超7%&#xff0c;药易购跌超6%&#xff0c;开开实业跌超3%。 值得注意的是&#xff0c;开开实业此前7个交易日斩…

08-信息收集-架构、搭建、WAF等

信息收集-架构、搭建、WAF等 信息收集-架构、搭建、WAF等一、前言说明二、CMS识别技术三、源码获取技术四、架构信息获取技术五、站点搭建分析1、搭建习惯-目录型站点2、搭建习惯-端口类站点3、搭建习惯-子域名站点4、搭建习惯-类似域名站点5、搭建习惯-旁注&#xff0c;c段站点…

leetcode做题笔记86分隔链表

给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&am…

详细安装配置django

安装配置使用Django。 1&#xff0c;下载安装 django pip install django 2.创建设置项目 先进入要放置项目的文件夹下 2.1&#xff0c; 创建项目 django-admin startproject Api_project 2.2&#xff0c; 创建app命令 cd Api_project dir看一下是否有 manage.py 文件…

新能源电动车充电桩控制主板的三大保护功能

新能源电动车充电桩控制主板的三大保护功能 你是否曾经遇到过电动车充电时电流过大&#xff0c;电压不稳定&#xff0c;或者电池过热的情况?这些问题都可能会给你的电动车带来安全隐患。那么&#xff0c;如何避免这些问题的发生呢?让我们一起来探讨一下充电桩控制主板的保护功…

剑指Offer68-II.二叉树的最近公共祖先 C++

1、题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以…

Java之抽象类

Java之抽象类 抽象类概念抽象类如何使用抽象类的特性 作者简介&#xff1a; zoro-1&#xff0c;目前大一&#xff0c;正在学习Java&#xff0c;数据结构等 作者主页&#xff1a;zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f49…

使用JMeter创建数据库测试

好吧&#xff01;我一直觉得我不聪明&#xff0c;所以&#xff0c;我用最详细&#xff0c;最明了的方式来书写这个文章。我相信&#xff0c;我能明白的&#xff0c;你们一定能明白。 我的环境&#xff1a;MySQL&#xff1a;mysql-essential-5.1.51-win32 jdbc驱动&#xff1a;…

设计模式之适配器模式(Adapter)的C++实现

1、适配器模式的提出 在软件功能开发中&#xff0c;由于使用环境的改变&#xff0c;之前一些类的旧接口放在新环境的功能模块中不再适用。如何使旧接口能适用于新的环境&#xff1f;适配器可以解决此类问题。适配器模式&#xff1a;通过增加一个适配器类&#xff0c;在适配器接…

【Rust】Rust学习 第十三章Rust 中的函数式语言功能:迭代器与闭包

Rust 的设计灵感来源于很多现存的语言和技术。其中一个显著的影响就是 函数式编程&#xff08;functional programming&#xff09;。函数式编程风格通常包含将函数作为参数值或其他函数的返回值、将函数赋值给变量以供之后执行等等。 更具体的&#xff0c;我们将要涉及&#…

详谈MongoDB的那些事

概念区分 什么是关系型数据库 关系型数据库&#xff08;Relational Database&#xff09;是一种基于关系模型的数据库管理系统&#xff08;DBMS&#xff09;。在关系型数据库中&#xff0c;数据以表格的形式存储&#xff0c;表格由行和列组成&#xff0c;行表示数据记录&…

PAT 1018 Public Bike Management

个人学习记录&#xff0c;代码难免不尽人意。 There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over the world. One may rent a bike at any station and return it to any other stations in the city. The Pu…

Java进阶(3)——手动实现ArrayList 源码的初步理解分析 数组插入数据和删除数据的问题

目录 引出手动实现ArrayList定义接口MyList<T>写ArrayList的实现类增加元素删除元素 写测试类进行测试数组插入数据? 总结 引出 1.ArrayList的结构分析&#xff0c;可迭代接口&#xff0c;是List的实现&#xff1b; 2.数组增加元素和删除元素的分析&#xff0c;何时扩容…

煤矿调度IP语音对讲广播模块一键求助对讲矿用调度通信系统SIP语音对讲求助终端

硬件接口描述 SV-2101VP/ SV-2103VP系列网络音频模块&#xff0c;所有外部连接采用端子&#xff0c;电源采用2.0mm的端子&#xff0c;网络采用标准RJ45连接器&#xff0c;其他都是1.25mm的连接器。 端口类型定义 P ———— 电源 AI ———— 模拟输入&#xff08;在这里是音…

《人工智能大模型体验报告2.0》发布

ChatGPT 崛起引发新一轮生成式AI热潮&#xff0c;国内科技企业纷纷布局。据不完全统计&#xff0c;截至目前&#xff0c;国内大模型数量已达上百个。在这些大模型中&#xff0c;谁的表现最好&#xff0c;智能性最高&#xff0c;用户体验最强&#xff1f;8月12日&#xff0c;新华…

谈谈召回率(R值),准确率(P值)及F值

通俗解释机器学习中的召回率、精确率、准确率&#xff0c;一文让你一辈子忘不掉这两个词 赶时间的同学们看这里&#xff1a;提升精确率是为了不错报、提升召回率是为了不漏报 先说个题外话&#xff0c;暴击一下乱写博客的人&#xff0c;网络上很多地方分不清准确率和精确率&am…

仿牛客论坛项目day7|Kafka

一、阻塞队列 创建了一个生产者线程和一个消费者线程。生产者线程向队列中放入元素&#xff0c;消费者线程从队列中取出元素。我们可以看到&#xff0c;当队列为空时&#xff0c;消费者线程会被阻塞&#xff0c;直到生产者线程向队列中放入新的元素。 二、Kafka入门 发布、订阅…

线性代数3,什么是向量 向量空间(草稿,建设ing)

列向量 行向量 4 什么是向量空间&#xff0c;向量的张成空间 域&#xff0c;组等概念 空间 向量空间 张成空间 6 线性代数 普通代数&#xff0c;是以单个的数为研究对象的数学 线性代数本质是以数组&#xff08;数组/向量&#xff1a;多个数为整体&#xff09;为基本对象的…

Mathematica 与 Matlab 常见复杂指令集汇编

Mathematica 常见指令汇编 Mathematica 常见指令 NDSolve 求解结果的保存 sol NDSolve[{y[x] x^2, y[0] 0, g[x] -y[x]^2, g[0] 1}, {y, g}, {x, 0, 1}]; numericSoly sol[[1, 1, 2]]; numericSolg sol[[1, 2, 2]]; data Table[{x, numericSoly[x], numericSolg[x]},…