当前位置: 首页 > news >正文

Golang中rune和Byte,字符和字符串有什么不一样

Rune和Byte,字符和字符串有什么不一样

String

Go语言中, string 就是只读的采用 utf8 编码的字节切片(slice) 因此用 len 函数获取到的长度并不是字符个数,而是字节个数。 for循环遍历输出的也是各个字节。

Rune

runeint32 的别名,代表字符的Unicode编码,采用4个字节存储,将 string 转成 rune 就意味着任何一个字符都用4个字节来存储其unicode值,这样每次遍历的时候返回的就是unicode值,而不再是字节了,这样就可以解决乱码问题了

byte

bytes操作的对象也是字节切片,与string的不可变不同,byte是可变的,因此string按增量方式构建字符串会导致多次内存分配和复制,使用bytes就不会因而更高效一点

 

在Go语言中,所谓的RuneByte其实分别就是int32有符号整数类型和uint8无符号整数类型的别称

也就是说

Rune=int32

Byte=unit8

为了理解Rune和Byte的作用,我们必须知道字符和字符串的区别。

字符和字符串的区别在于字符表达的是单一的字母、数字、空格、标点符号而字符串表达的是一个或多个字母、数字、空格和标点符号。和C、Java等语言不同,Go语言中并没有char这个专门用来表示字符的数据类型,而是使用Rune和Byte来表达字符。因此Rune虽然是有符号整数类型的一种,但它通常不用于表示231 到 231-1这些整数,而是用来表示长度可以达到32bit的字符(比如Unicode编码格式的字符),之前我们讲到在对中文字符串做切片时必须将字符串先从默认的8bit的Byte(前面讲到了,在Go中,所谓字符串就是一组字节的切片(slice of bytes))转换成32bit的Rune否则的话会出现乱码就是这个原因,因为汉字通常需要3个字节(24bit)来表示。

而和unit8等价的Byte其实就是我们通常理解的字节,既计算机中最常见的存储单位(1 byte = 8 bits, 1024 bytes = 1 kilobyte, 1024 kilobytes = 1 megabyte…)。和Rune类似,Byte虽然是无符号整数类型的一种,但是它主要的作用并不是用来表示0到255这些整数,而是用来表示长度为8bit的字符。

和用双引号声明的字符串不一样,在Go中我们用单引号来声明一个字符,字符有两种数据类型:Rune和Byte,默认情况下字符的类型为Rune(即隐式声明字符变量时其类型为Rune),举例如下:

func main() {var a rune = 'A'fmt.Println(a)fmt.Printf("%T\n", a)var b = '中'fmt.Println(b)fmt.Printf("%T\n", b)
}

输出:

 

这里我们以显示的方式声明了字符变量a,以隐式的方式声明了字符变量b,此时a和b的类型都为Rune,即int32。

这里你也许会问:为什么我们赋值给变量a的是字符“A”,赋值给变量b的是字符“中”,但变量a和b打印出来的结果却是整数65和20013?这是因为不管是Rune还是Byte,它们的本质还是整数,而字符“A”对应的整数即为65,字符“中”对应的整数即为20013。如果要想将变量a和变量b打印出的内容以原本的字符内容显示,则需要用到格式码%c或者string()函数来将字符转变为字符串,举例如下:

func main() {var a rune = 'A'fmt.Printf("%c\n", a)fmt.Printf("%T\n", a)var b = '中'fmt.Println(string(b))fmt.Printf("%T\n", b)
}

输出:

 

因为默认情况下字符的类型为Rune,如果要创建一个Byte类型的字符变量的话,则必须显示声明变量的类型,举例如下:

func main() {var a byte = 'A'fmt.Printf("%c\n", a)fmt.Printf("%T\n", a)var b byte = '中'fmt.Printf("%c\n", b)fmt.Printf("%T\n", b)
}

 

输出:

这里在运行该程序时出现了“.\integer.go:9:6: constant 20013 overflows byte”的报错,原因也很简单:Byte对应的是无符号整数类型uint8,而uint8的范围是0到255,而字符"中"对应的整数为20013,显然20013不在unit8的范围内,因此会报错。解决的办法就是避免将中文字符赋值以Byte的类型赋值给变量,因为Byte对应的是ASCII编码,而中文对应的是Unicode或UTF-8,需要用到Rune。

最后再强调一次:字符表达的是单一的字母、数字、空格、标点符号,在使用rune或者byte来声明一个字符变量时,如果字符内容里哪怕只多出1个字母、数字、空格、标点符号,那都是无效的字符,Go会返回"more than one character in rune literal"的异常,举例如下:

func main() {var r1 rune = 'a'fmt.Println(string(r1))var r2 rune = 'ab'fmt.Println(string(r2))
}

输出:

 

这里我们分别声明了r1和r2两个rune类型的字符,r1是正常的字符,而r2仅仅因为在字符a后面多加了一个b就导致了Go返回了"more than one character in rune literal"这个异常。

字符串

字符串,可以说是大家很熟悉的数据类型之一。定义方法很简单
var mystr string = "hello"
 

 

上面说的byte 和 rune 都是字符类型,若多个字符放在一起,就组成了字符串,也就是这里要说的 string 类型。

比如 hello ,对照 ascii 编码表,每个字母对应的编号是:104,101,108,108,111

如下示例:

func main() {var mystr01 string = "hello"var mystr02 [5]byte = [5]byte{104, 101, 108, 108, 111}fmt.Printf("mystr01: %s\n", mystr01)fmt.Printf("mystr02: %s", mystr02)
}

输出:

 

mystr01 和 mystr02 输出一样,说明了 string 的本质,其实是一个 byte数组

通过以上学习,我们知道字符分为 byte 和 rune,占用的大小不同。

hello,中国 占用几个字节?

要回答这个问题,你得知道 Go 语言的 string 是用 uft-8 进行编码的,

英文字母占用一个字节,而中文字母占用 3个字节

所以 hello,中国 的长度为 5+1+(3*2)= 12个字节。

func main() {var country string = "hello,中国"fmt.Println(len(country))
}

 输出:

以上虽然我都用双引号表示 一个字符串,但这并不是字符串的唯一表示方式。

除了双引号之外 ,你还可以使用反引号

大多情况下,二者并没有区别,但如果你的字符串中有转义字符\ ,这里就要注意了,它们是有区别的。

使用反引号号包裹的字符串,相当于 Python 中的 raw 字符串,会忽略里面的转义。

比如我想表示 \r\n 这个 字符串,使用双引号是这样写的,这种叫解释型表示法

var mystr01 string = "\\r\\n"

而使用反引号,就方便多了,所见即所得,这种叫原生型表示法

var mystr02 string = `\r\n`

相关文章:

Golang中rune和Byte,字符和字符串有什么不一样

Rune和Byte,字符和字符串有什么不一样 String Go语言中, string 就是只读的采用 utf8 编码的字节切片(slice) 因此用 len 函数获取到的长度并不是字符个数,而是字节个数。 for循环遍历输出的也是各个字节。 Rune rune 是 int32 …...

实施工程师运维工程师面试题

Linux 1.请使用命令行拉取SFTP服务器/data/20221108/123.csv 文件,到本机一/data/20221108目录中。 使用命令行拉取SFTP服务器文件到本机指定目录,可以使用sftp命令。假设SFTP服务器的IP地址为192.168.1.100,用户名为username,密…...

6-13连接两个字符串

#include<stdio.h> int main(){int i0,j0;char s1[222],s2[333];printf("请输入第一个字符串&#xff1a;\n");gets(s1);//scanf("%s",s1);printf("请输入第二个字符串&#xff1a;\n");gets(s2);while(s1[i]!\0)i;while(s2[j]!\0)s1[i]s2…...

Linux中的文件IO

文章目录 C语言文件操作系统文件I/O接口介绍 open函数返回值文件描述符fd0 & 1 & 2文件描述符的分配规则 重定向使用 dup2 系统调用 FILE理解文件系统理解硬链接软链接acm 动态库和静态库静态库与动态库生成静态库生成动态库&#xff1a; C语言文件操作 先来段代码回顾…...

深度学习记录--初识向量化

什么是向量化&#xff1f; 之前计算logistic回归损失函数时&#xff0c;在代码实现时&#xff0c;讨论了for循环&#xff1a;过多的for循环会拖慢计算的速度(尤其当数据量很大时) 因此&#xff0c;为了加快计算&#xff0c;向量化是一种手段 运用python的numpy库&#xff0c…...

树与二叉树堆:经典OJ题集(2)

目录 二叉树的性质及其问题&#xff1a; 二叉树的性质 问题&#xff1a; 一、对称的二叉树&#xff1a; 题目&#xff1a; 解题思路&#xff1a; 二、另一棵树&#xff1a; 题目&#xff1a; 解题思路&#xff1a; 三、翻转二叉树&#xff1a; 题目&#xff1a;…...

Java面试题(每天10题)-------连载(40)

目录 Mysql篇 1、表中有大字段X&#xff08;例如&#xff1a;text类型&#xff09;&#xff0c;且字段X不会经常更新&#xff0c;将该字段拆成子表好处是什么&#xff1f; 2、Mysql中InnoDB引擎的行锁是通过加载什么上完成的&#xff1f; 3、Mysql中控制内存分配的全局参数…...

2023年【起重机司机(限桥式起重机)】报名考试及起重机司机(限桥式起重机)考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年【起重机司机(限桥式起重机)】报名考试及起重机司机(限桥式起重机)考试资料&#xff0c;包含起重机司机(限桥式起重机)报名考试答案和解析及起重机司机(限桥式起重机)考试资料练习。安全生产模拟考试一点通结合…...

Linux的基本指令(3)

目录 制作小文件&查看 nano指令 cat指令 tac指令 制作大文件&查看 一切皆文件 echo指令 > 输出重定向 以写"w"的形式打开文件 以追加"a"的形式打开文件 cat指令 < 输入重定向 创建big.txt more指令 less指令&#xff08;推…...

C语言memcpy,memmove的介绍及模拟实现

文章目录 每日一言memcpy介绍模拟实现 memmove介绍模拟实现思路代码 结语 每日一言 If you want to lift yourself up, lift up someone else. 如果你想振奋自己&#xff0c; 先振奋周遭的人。 memcpy 介绍 函数原型&#xff1a; void *memcpy(void *dest, const void *sr…...

克服.360勒索病毒:.360勒索病毒的解密和预防

导言: 在数字化的今天&#xff0c;数据安全问题变得愈发棘手。.360勒索病毒是当前网络空间的一场潜在灾难&#xff0c;对于这个威胁&#xff0c;了解应对之道和采取切实的预防措施至关重要。如果您正在经历勒索病毒的困境&#xff0c;欢迎联系我们的vx技术服务号&#xff08;s…...

21、Resnet50 中包含哪些算法?

(本文已加入“计算机视觉入门与调优”专栏,点击专栏查看更多文章信息) 这一节汇总一下resnet50 中包含的算法,并且简单介绍。 总共卷积算法、激活算法(relu)、最大池化算法、加法(主要是为了实现残差结构)、全局平均池化、全连接和 softmax 算法这几种算法。 卷积 卷…...

pybind11教程

pybind11教程 文章目录 pybind11教程1. pybind11简介2. cmake使用pybind11教程3. pybind11的历史 1. pybind11简介 项目的GitHub地址为&#xff1a; pybind11 pybind11 是一个轻量级的头文件库&#xff0c;用于在 Python 和 C 之间进行互操作。它允许 C 代码被 Python 调用&am…...

Java基础- 自定义类加载器

自定义类加载器 在 Java 中实现自定义类加载器通常涉及继承 ClassLoader 类并重写其 findClass 方法。自定义类加载器允许我们从非标准来源&#xff08;如网络、加密文件或其他媒体&#xff09;加载类。下面是实现自定义类加载器的基本步骤&#xff1a; 1. 继承 ClassLoader …...

2022年高校大数据挑战赛A题工业机械设备故障预测求解全过程论文及程序

2022年高校大数据挑战赛 A题 工业机械设备故障预测 原题再现&#xff1a; 制造业是国民经济的主体&#xff0c;近十年来&#xff0c;嫦娥探月、祝融探火、北斗组网&#xff0c;一大批重大标志性创新成果引领中国制造业不断攀上新高度。作为制造业的核心&#xff0c;机械设备在…...

洛谷 P1998 阶乘之和 C++代码

前言 今天我们来做洛谷上的一道题目。 网址&#xff1a;[NOIP1998 普及组] 阶乘之和 - 洛谷 西江月夜行黄沙道中 【宋】 辛弃疾 明月别枝惊鹊&#xff0c;清风半夜鸣蝉。稻花香里说丰年&#xff0c;听取WA声一片。 七八个星天外&#xff0c;两三点雨山前。旧时茅店社林边&…...

洛谷 B2006 地球人口承载力估计 C++代码

目录 前言 思路点拨 AC代码 结尾 前言 今天我们来做洛谷上的一道题目。 网址&#xff1a;地球人口承载力估计 - 洛谷 题目&#xff1a; 思路点拨 经典牛吃草问题。 解设一个人一年吃一份草。 则x*a-y*b为会多出的草&#xff0c;为什么会多呢&#xff1f;是因为每年都有…...

少走弯路:OpenCV、insightface 等多方案人脸推理和识别

脑壳有包又花时间折腾了一下&#xff0c;其实之前也折腾过&#xff0c;主要是新看了一个方法 在下图中查找脸部 第一种方案&#xff1a; 使用了opencv 的cv2.FaceDetectorYN. &#xff0c;完整代码如下&#xff1a; import numpy as np import cv2imgcv2.imread("00000…...

github代码连接vercel 建立一个公用网站

Deploying to the Cloud using Vercel 前置任务 建立一个基于flask的web app代码库并上传至github repo Vercel用途 vercel有点像一个免费的cloud server&#xff0c;帮助你将flask框架下的程序运行在云端。可以public访问。 deploy流程 在主文件夹中建立requirements.tx…...

使用pandas将字符串格式数据转换为单独的行

有时在处理数据时&#xff0c;可能会遇到这样的情况&#xff0c;即数据框中的整个字符串条目需要拆分到不同的行中。这可能是一项具有挑战性的任务&#xff0c;特别是当数据庞大而复杂时。尽管如此&#xff0c;一个名为pandas的Python库提供了各种函数&#xff0c;使用这些函数…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...