Golang——rune和byte

本文详细介绍Golang中的两种字符类型rune和byte,介绍他们的区别,编码方式和简单的使用。

在这里插入图片描述

文章目录

      • `byte` 类型
      • `rune` 类型
      • UTF-8 与 Unicode 的关系
      • byte和rune的主要区别
      • Go的默认编码方式
      • 遍历方式
        • 遍历 `byte`
        • 遍历 `rune`
        • 补充
      • 字符还原
        • 从 `byte` 序列还原字符串
        • 从 `rune` 序列还原字符串

在Go语言中,runebyte都是表示单个字符的类型,但它们有一些关键的区别。

byte 类型

byteuint8 的别名,即一个 8 位无符号整数,表示一个字节,范围是 0 到 255。

  • byte 用于表示 UTF-8 编码中的 字节,适合处理字节流和 ASCII 字符。

字符占用字节数:

  • ASCII 字符(0-127)占用 1 字节。
  • 常见的字符,如拉丁字母、标点符号,占用 1 字节。
  • 中文等非 ASCII 字符会占用 3 字节。

byte 表示:字符串 "你",它在 Go 中的 UTF-8 编码是 0xE4, 0xBD, 0xA0(十六进制)。

s := "你"
for i := 0; i < len(s); i++ {
    fmt.Printf("byte at index %d: %d\n", i, s[i])
}

输出:

byte at index 0: 228
byte at index 1: 189
byte at index 2: 160

rune 类型

runeint32 的别名,即一个 32 位有符号整数,用于表示一个 Unicode 字符。Go中所有字符(包括 ASCII 和 Unicode 字符)都是以 rune 类型表示的,范围是 0 到 0x10FFFF。

  • rune 用于表示 Unicode 字符,它表示字符的 编码点,适合处理字符操作,尤其是涉及 Unicode 字符(如中文、表情符号等)。

rune 表示:

s := "你"
for _, c := range s {
    fmt.Printf("rune: %c, rune value: %d\n", c, c)
}

输出:

rune: 你, rune value: 20320

这表示 "你" 的 Unicode 编码点(20320,即 0x4F60)被 rune 类型存储。

UTF-8 与 Unicode 的关系

  • Unicode 是字符集,而 UTF-8 是 Unicode 字符集的编码方式之一。Unicode 定义了所有字符的编码点,但它并没有规定字符如何存储和传输。为了实现跨平台和跨语言的兼容,UTF-8 被定义为一种将 Unicode 编码点转换为字节序列的方式。除了 UTF-8 外,还有 UTF-16 和 UTF-32。
  • 联系
    • Unicode 为每个字符分配一个编码点(一个数字)。
    • UTF-8 通过不同长度的字节序列来编码这些 Unicode 编码点,使得它们可以被存储在文件中、传输通过网络、显示在屏幕上等。

byte和rune的主要区别

特性byterune
类型uint8 (8-bit unsigned int)int32 (32-bit signed int)
用途处理 ASCII 或字节数据处理 Unicode 字符
表示范围0 到 2550 到 0x10FFFF
常见应用字节流、ASCII字符Unicode字符(包括多字节字符)
存储大小1 字节4 字节
字符集支持仅支持 ASCII 字符支持所有 Unicode 字符

Go的默认编码方式

Go 字符串默认的编码方式是 UTF-8 。所以默认使用 byte 序列来表示字符串中的每个字符。

具体来说,Go 中的字符串(string 类型)是由 UTF-8 编码的字节序列 组成的。因此:

  • 一个 Go 字符串是由多个字节(byte)组成的,每个字节都是 UTF-8 编码的一个字符。
  • 这些字节遵循 UTF-8 编码,Go 字符串既可以包含 ASCII 字符(这些字符在 UTF-8 中占用 1 个字节),也可以包含多字节的 Unicode 字符(如中文字符,这些字符在 UTF-8 中通常占用 3 个字节)。
s := "a"
fmt.Print("占用字节数:", len(s))
fmt.Printf(";类型:%T  ", s[0])
fmt.Println()
s1 := "你"
fmt.Print("占用字节数:", len(s1))
fmt.Printf(";类型:%T  ", s1[0])

输出:

占用字节数:1;类型:uint8  
占用字节数:3;类型:uint8  

遍历方式

遍历 byte

bytes := []byte(s)可以直接将字符串转为byte,当然也可以遍历:

  • 使用 for i := 0; i < len(s); i++,每次迭代都可以访问字符串中的每个字节。
  • len(s) 返回字符串的 字节数(byte),即字符串中包含的字节总数,而不是字符的数量。对于一个包含多字节字符(如中文字符)的字符串,len(s) 返回的是字符串所占用的字节数。
package main

import "fmt"

func main() {
	s := "你" // 包含中文字符

	// 按字节遍历字符串
	fmt.Println("按字节遍历字符串:")
	for i := 0; i < len(s); i++ {
		fmt.Printf("s[%d] = %v (类型: %T)\n", i, s[i], s[i]) // 输出每个字节的值
	}
}

输出:

按字节遍历字符串:
s[0] = 228 (类型: uint8)
s[1] = 189 (类型: uint8)
s[2] = 160 (类型: uint8)
遍历 rune

runes := []rune(s)可以直接将字符串转为rune,当然也可以遍历:

  • 使用 for _, c := range s 遍历字符串时,Go 会自动将字符串 s 中的每个字符解码成 rune 类型,这样即使字符是多字节的,也能正确处理。

  • range 遍历字符串时,按 字符(rune) 进行迭代。每次迭代返回一个 Unicode 码点(rune) 和该字符在字符串中的索引。对于多字节字符,range 会自动跳过这些字节,按字符来迭代。

package main

import "fmt"

func main() {
	s := "你"

	// len(s) 返回字节数
	fmt.Println("len(s) =", len(s)) // 输出:3,因为“你”是由 3 个字节表示

	// 使用 range 遍历字符串,按字符(rune)遍历
	fmt.Println("使用 range 遍历字符串,按字符(rune)遍历:")
	for i, r := range s {
		fmt.Printf("i = %d, r = %v (类型: %T)\n", i, r, r)
	}
}

输出:

len(s) = 3
使用 range 遍历字符串,按字符(rune)遍历:
i = 0, r = 20320 (类型: int32)
补充

for i := range s 的 s[i] 其实也是byte,但是处理中文时候会存在问题。

  • 当你使用for i := range s 处理英文字符串的时候,可能不会有问题,因为英文字符(ASCII 字符)在 UTF-8 编码中是单字节表示的,所以每个字符正好对应一个字节。

  • 但是如果字符串中包含非英文字符(如中文、表情符号等),它们通常会占用多个字节。在这种情况下。使用for i := range s 就会发现问题,range 会按照字符(rune)进行遍历,统计的数量是字符数(rune)【如下只有1个】,而不是字节数(byte)【一个中文,应该是对应3个字节】。

package main

import "fmt"

func main() {
	s := "你" // 字符串包含中文字符

	// 使用 range 遍历字符串
	fmt.Println("使用 range 遍历字符串:")
	for i := range s {
		fmt.Printf("s[%d] = %v (类型: %T)\n", i, s[i], s[i]) // 打印每个字节的值
	}
}

输出:

使用 range 遍历字符串:
s[0] = 228 (类型: uint8)

字符还原

要从 byte 序列或 rune 序列还原回原始字符串,你可以通过以下方式进行操作:

  • byte 序列还原字符串:可以直接使用 string(byteSlice)
  • rune 序列还原字符串:可以直接使用 string(runeSlice)
byte 序列还原字符串
package main

import "fmt"

func main() {
	s := "你好" // 字符串 "你好"

	// 将字符串转换成 rune 切片
	bytes := []byte(s)

	fmt.Println("bytes:", bytes)
	// 将 rune 切片转换回字符串
	s1 := string(bytes)
	fmt.Println("还原的字符串:", s1)
}

bytes: [228 189 160 229 165 189]
还原的字符串: 你好
rune 序列还原字符串
package main

import "fmt"

func main() {
	s := "你好" // 字符串 "你好"

	// 将字符串转换成 rune 切片
	runes := []rune(s)

	fmt.Println("runes编码:", runes)
	// 将 rune 切片转换回字符串
	s1 := string(runes)
	fmt.Println("还原的字符串:", s1)
}


runes编码: [20320 22909]
还原的字符串: 你好

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于当前最前沿的前端(Vue3 + Vite + Antdv)和后台(Spring boot)实现的低代码开发平台

项目是一个基于当前最前沿的前端技术栈&#xff08;Vue3 Vite Ant Design Vue&#xff0c;简称Antdv&#xff09;和后台技术栈&#xff08;Spring Boot&#xff09;实现的低代码开发平台。以下是对该项目的详细介绍&#xff1a; 一、项目概述 项目名称&#xff1a;lowcode-s…

java springboot3.x jwt+spring security6.x实现用户登录认证

springboot3.x jwtspring security6.x实现用户登录认证 什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;它用于在网络应用环境中传递声明。通常&#xff0c;JWT用于身份验证和信息交换。JWT的一个典型用法是…

代码随想录刷题day07|(数组篇)58.区间和

目录 一、数组理论基础 二、前缀和 三、相关算法题目 四、总结 五、待解决问题 一、数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合。 代码随想录 (programmercarl.com) 特点&#xff1a; 1.下标从0开始&#xff0c;内存中地址空间是连续的 2.查询快&…

专用小软件,完全免费,非常丝滑

今天给大家介绍一个专门将PDF数电发票合并打印的软件&#xff0c;这个软件可以批量操作&#xff0c;完全免费没有任何的广告。 电子发票专用批量打印工具 免费批量使用 软件无需安装&#xff0c;解压之后双击这个图标就能直接使用了。 点击右上角的加号&#xff0c;选中需要打…

安装虚拟机VMware遇到的问题

问题1&#xff1a;进入如下界面&#xff0c;不知道如何操作 解决办法 键盘⬇️&#xff0c;选择“Reset the system”回车 问题2&#xff1a;系统存放位置我给放在了VMware安装目录&#xff0c;具体D:\software\VMware\Windows安装不行 解决办法&#xff1a;D:\software\virt…

Matlab 具有周期性分布的死角孔的饱和空气多孔材料的声学特性

本文对直主孔含侧空腔&#xff08;死角&#xff09;的饱和空气多孔介质中的声传播进行了理论和数值研究。侧腔位于沿每个主孔周期性间隔的“节点”上。研究了侧向空腔分布中周期性的影响&#xff0c;并单独考虑了紧间隔死角的低频极限。结果表明&#xff0c;吸附系数和透射损失…

Vue如何构建项目

目录 1.安装Node.js 2.换源(建议) 3.选择一个目录 4.创建一个vue项目 5.验证是否成功 1.安装Node.js 安装18.3或更⾼版本的 Nodejs 点击下载->Node.Js中文网 node -v npm -v 安装好后在windows的cmd窗口下运行 如果能运行出结果就说明安装好了。 2.换源(建议) //…

网络层协议-----IP协议

目录 1.认识IP地址 2.IP地址的分类 3.子网划分 4.公网IP和私网IP 5.IP协议 6.如何解决IP地址不够用 1.认识IP地址 IP 地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址。 它是分配给连接到互联网的设备&#xff08;如计算机、服务器、智能手机…

MacOS 下 Memory Analyzer 启动报错

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的全栈工程师 欢迎分享 / 收藏 / 赞 / 在看…

sql模糊关联匹配

需求目标&#xff1a; 建立临时表 drop table grafana_bi.zbj_gift_2024;USE grafana_bi; CREATE TABLE zbj_gift_2024 (id INT AUTO_INCREMENT PRIMARY KEY,userName VARCHAR(255),giftName VARCHAR(255),giftNum INT,points INT,teacher VARCHAR(255),sendDate DATETIME,…

automake error: version mismatch

automake error: version mismatch REF:automake 编译提示版本报错 解决高版本不兼容低版本

C++----STL(string)

引言&#xff1a;STL简介 什么是STL STL(standard template libaray-标准模板库)&#xff1a; 是 C标准库的重要组成部分&#xff08;注意&#xff1a;STL只是C标准库里的一部分&#xff0c;cin和cout也是属于C标准库的&#xff09;&#xff0c;不仅是一个可复用的组件库&…

如何选择视频文件

文章目录 1. 概念介绍2. 方法与细节2.1 实现方法2.2 具体细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何选择多个图片文件"相关的内容&#xff0c;本章回中将介绍如何选择视频文件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在前…

C++中的STL

STL&#xff08;标准模板库&#xff09;在广义上分为&#xff1a;容器&#xff0c;算法&#xff0c;迭代器 容器和算法之间通过迭代器进行无缝衔接 STL大体上分为六大组件:分别为容器&#xff0c;算法&#xff0c;迭代器&#xff0c;仿函数&#xff0c;适配器&#xff0c;空间…

Windows下安装和配置Go开发环境

文章目录 1. 介绍了SDK2. 下载 SDK工具包3. windows 下配置 Golang 环境变量 1. 介绍了SDK SDK 的全称(Software Development Kit 软件开发工具包)SDK是提供给开发人员使用的&#xff0c;其中包含了对应开发语言的工具包 2. 下载 SDK工具包 Go语言的官网为&#xff1a;https…

riscv架构下linux4.15实现early打印

在高版本linux6.12.7源码中&#xff0c;early console介绍&#xff0c;可参考《riscv架构下linux6.12.7实现early打印》文章。 1 什么是early打印 适配内核到新的平台&#xff0c;基本环境搭建好之后&#xff0c;首要的就是要调通串口&#xff0c;方便后面的信息打印。 正常流…

HarmonyOS 鸿蒙 ArkTs(5.0.1 13)实现Scroll下拉到顶刷新/上拉触底加载,Scroll滚动到顶部

HarmonyOS 鸿蒙 ArkTs(5.0.1 13)实现Scroll下拉到顶刷新/上拉触底加载 效果展示 使用方法 import LoadingText from "../components/LoadingText" import PageToRefresh from "../components/PageToRefresh" import FooterBar from "../components/…

《自动驾驶与机器人中的SLAM技术》ch9:自动驾驶车辆的离线地图构建

目录 1 点云建图的流程 2 前端实现 2.1 前端流程 2.2 前端结果 3 后端位姿图优化与异常值剔除 3.1 两阶段优化流程 3.2 优化结果 ① 第一阶段优化结果 ② 第二阶段优化结果 4 回环检测 4.1 回环检测流程 ① 遍历第一阶段优化轨迹中的关键帧。 ② 并发计算候选回环对…

鸿蒙面试 2025-01-10

写了鉴权工具&#xff0c;你在项目中申请了那些权限&#xff1f;&#xff08;常用权限&#xff09; 位置权限 &#xff1a; ohos.permission.LOCATION_IN_BACKGROUND&#xff1a;允许应用在后台访问位置信息。 ohos.permission.LOCATION&#xff1a;允许应用访问精确的位置信息…

Windows图形界面(GUI)-QT-C/C++ - QT控件创建管理初始化

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 控件创建 包含对应控件类型头文件 实例化控件类对象 控件设置 设置父控件 设置窗口标题 设置控件大小 设置控件坐标 设置文本颜色和背景颜色 控件排版 垂直布局 QVBoxLayout …