【Go面试向】rune和byte类型的认识与使用

news2024/10/2 3:17:27

【Go】rune和byte类型的认识与使用

大家好 我是寸铁👊
总结了一篇rune和byte类型的认识与使用的文章✨
喜欢的小伙伴可以点点关注 💝

byte和rune类型定义

byte,占用1个字节,共8个比特位,所以它实际上和uint8没什么本质区别,它表示的是一个ASCII码字符。

rune,占用4个字节,共32个比特位,所以它实际上和int32没什么本质区别,它表示的是一个Unicode字符
(Unicode是一种能表示世界上绝大部分字符的编码格式)


不妨来验证一下,能否用uint8和byte一样去表示一个字符,能否用int32和rune一样去表示一个字符?

Demo

package main

import "fmt"

func main() {

    //byte与uint32
    var a byte = 'a'
    var b uint8 = 'a'
    fmt.Println("使用byte类型表示字符:", string(a))    //a
    fmt.Println("使用uint8类型表示字符串: ", string(b)) //a

    fmt.Println("---------------")
    var c rune = 'b'
    var d int32 = 'b'
    fmt.Println("使用rune类型表示字符:", string(c))    //b
    fmt.Println("使用int32类型表示字符串: ", string(d)) //b
}

运行结果如下:
答案是可以的,也证明了这两种实际上并无本质区别。
在这里插入图片描述


这次来验证一下,能否用uint8和byte数组去表示一个字符串,能否用int32和rune数组一样去表示一个字符串?

demo

package main

import "fmt"

func main() {
    str := "nana"
    s := []byte(str)
    fmt.Println("使用byte类型表示字符串: ", string(s)) //nana

    str1 := "nana"
    s1 := []uint8(str1)
    fmt.Println("使用uint8类型表示字符串: ", string(s1)) //nana

    fmt.Println("____________________")
    str2 := "nanago"
    s2 := []rune(str2)
    fmt.Println("使用rune类型表示字符串: ", string(s2)) //nanago

    str3 := "nanago"
    s3 := []int32(str3)
    fmt.Println("使用int32类型表示字符串: ", string(s3)) //nanago
}

运行结果如下:
答案是可以的,也证明了这两种实际上并无本质区别。
在这里插入图片描述


有人会问:既然本质没什么区别,为什么还要创建byte和rune类型?

这就涉及到类型别名的概念,众所周知,Go语言有两种类型声明方式:一种叫类型定义声明;另一种叫类型别名声明。其中,别名的使用在大型项目重构中作用最为明显,它能够解决代码升级或者迁移过程中可能存在的类型兼容性问题。而runebyte是Go语言中仅有的两个类型别名,专门用于处理字符。当然,我们可以通过type等关键字加=号的方式声明更多的类型别名。

rune的使用

我们知道,字符串由字符组成,字符的底层由字节组成,而一个字符串的底层的表示是一个字节序列(数组)。在Go语言中,字符可以被分成两种类型处理: 对占一个字节的英文类字符,可以使用byte或者uint8。对占1~4个字节的其他字符,可以使用rune或者int32,如中文、日文、特殊符号等。
示例说明:

rune类型表示中文符号

如下图:这说明可以用rune表示中文符号,不能用byte表示中文符号,没有定义rune类型去表示中文符号,会出现溢出现象。
为什么会出现精度溢出?
很明显,刚才说到byte是一个字节,而rune1~4个字节。我们知道,英文是1个字节,中文是3个字节。byte最多只能表示一个字节的字符,但是,中文是3个字节的,byte1个字节去表示3个字节的字符,必定是不够的,也就造成overflow(溢出)现象。

demo


package main

import "fmt"

func main() {

    //使用rune类型表示一个中文 一个字符 字节序列
    var a rune = '云'
    fmt.Println(string(a))
    var b byte = '云'
    fmt.Println(string(b))
    //统计带中文的字符串长度

}

运行结果如下:
在这里插入图片描述

所以,rune的第一个作用是表示中文符号。

统计字符串的长度

举个例子:统计带中文的字符串的长度

demo


package main

import "fmt"

func main() {

    //统计带中文字符串的长度
    fmt.Println(len("Go语言编程")) //14

    //转换为rune数组后统计带中文字符串的长度
    fmt.Println(len([]rune("Go语言编程"))) //6

}

运行结果如下:
在这里插入图片描述

分析一下结果:为什么直接打印就是14,转换为rune[]数组后打印为6?
分析:字符串在底层表示的是一个字节(byte)序列。其中,英文字符占用1个字节,中文字符占用3个字节。所以得到的是1+1+3*4 = 14,是底层中字节序列占用字节的长度,而不是字符的长度。使用rune[]数组后,便可以统计出带中文字符串的字符长度

所以,第二个功能是统计字符串的长度。

截取字符串

举个例子:截取带中文的字符串
截取Go语言这一段,字符串的底层是一个字节序列(数组),字符串的截取 左闭右开 1+1+3+3=8 下标从0开始,起始索引为0,终止索引为8(考虑到右边为开区间)。

demo

    s := "Go语言编程"
    fmt.Println(s[0:8])
    //字符串的截取 左闭右开 1+1+3+3=8 下标从0开始

运行结果如下:
在这里插入图片描述

结果是对的,但是存在一个缺陷:就是每次截取时,必须先计算出需要截取的字符串的字节索引,如果说字节数计算错误,就会出现乱码的情况。

验证一下:

s := "Go语言编程"
fmt.Println(s[0:7])
s2 := "Go语言编程"
fmt.Println(s2[0:4])

运行结果如下:
很明显,出现乱码的情况。
在这里插入图片描述

除此之外,假设字符串的长度非常大,通过字节的方式去截取显然不是一个高效的方法。应该是取出字符的方式去截取字符串,rune类型便可以实现这一点。其实,从刚才的len取出byterune数组的长度就可以知道,rune是直接操作字符,而不是像byte一样去一个个操作字节。

使用rune类型运行截取字符串运行结果如下:
在这里插入图片描述

所以,rune的第三个功能是截取字符串。

rune实现分析

为什么rune类型可以做到这一点?
简述:
首先,先弄清楚string、byte、rune三者之间的关系。
字符串在底层的表示是由单个字节组成的一个不可修改的字节序列,字节使用UTF-8编码标识Unicode文本。Unicode文本意味着.go文件可以包含世界上的任意语言或者字符,该文件在任意系统上打开都不会乱码UTF-8Unicode的一种实现方式,是一种针对Unicode可变长度的字符编码,它定义了字符串以何种方式存储在内存中UTF-8使用1~4为每个字符编码。
Go语言把字符分为byterune两种类型处理,byteuint8类型的别名,用于存放占用1个字节的ASCII字符,如英文字符,返回的是字符的原始字节rune类型是int32类型的别名,用于存放多字节字符,如占3个字节的中文字符,返回的是字符Unicode码点值

验证一下
说明上述的分析成立!
demo

s := "Go语言编程"
fmt.Println("byte类型: ", []byte(s))
//输出: byte类型:  [71 111 232 175 173 232 168 128 231 188 150 231 168 139]

fmt.Println("rune类型: ", []rune(s))
//输出: rune类型:  [71 111 35821 35328 32534 31243]

具体实现细节参考下面网址:
https://www.cnblogs.com/cheyunhua/p/16007219.html

看到这里的小伙伴,恭喜你又掌握了一个知识点👊
希望大家能取得胜利,坚持就是胜利💪
我是寸铁!我们下期再见💕

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

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

相关文章

一文了解【完全合作关系】下的【多智能体强化学习】

处于完全合作关系的多智能体的利益一致,获得的奖励相同,有共同的目标。比如多个工业机器人协同装配汽车,他们的目标是相同的,都希望把汽车装好。 在多智能体系统中,一个智能体未必能观测到全局状态 S。设第 i 号智能体…

Nginx前后端分离部署springboot和vue项目

Nginx前后端分离部署springboot和vue项目,其实用的比较多,有的小伙伴对其原理和配置还一知半解,现在就科普一下: 1、准备后端项目 后端工程无论是微服务还是单体,一般最终都是jar启动,关键点就是把后端服…

vivado RTL运行方法检查、分析方法报告、报告DRC

运行方法检查 Vivado Design Suite提供基于超快设计的自动化方法检查使用“报告方法论”命令的FPGA和SoC(UG949)方法论指南。您可以生成关于打开、详细阐述、综合或实现的方法论报告设计对于详细设计,方法报告会检查XDC和RTL文件。对于有关使…

CVE重要通用漏洞复现java php

在进行漏洞复现之前我们需要在linux虚拟机上进行docker的安装 我不喜欢win上安因为不知道为什么总是和我的vmware冲突 然后我的kali内核版本太低 我需要重新安装一个新的linux 并且配置网络 我相信这会话费我不少时间 查看版本 uname -a 需要5.5或以上的版本 看错了浪…

滚动菜单+图片ListView

目录 Fruit.java FruitAdapter MainActivity activity_main.xml fruit.xml 整体结构 Fruit.java public class Fruit {private String name;private int imageId;public Fruit(String name, int imageId) {this.name name;this.imageId imageId;}public String getNam…

AR与AI融合加速,医疗护理更便捷

根据Reports and Data的AR市场发展报告,到2026年,预计医疗保健市场中的AR/VR行业规模将达到70.5亿美元。这一趋势主要受到对创新诊断技术、神经系统疾病和疾病意识不断增长的需求驱动。信息技术领域的进步,包括笔记本电脑、计算机、互联网连接…

用 Python 制作可视化 GUI 界面,一键实现自动分类管理文件!

经常杂乱无章的文件夹会让我们找不到所想要的文件,因此小编特意制作了一个可视化GUI界面,通过输入路径一键点击实现文件分门别类的归档。 不同的文件后缀归类为不同的类别 我们先罗列一下大致有几类文件,根据文件的后缀来设定,大…

Vue入门七(Vuex的使用|Vue-router|LocalStorage与SessionStorage和cookie的使用|路由的两种工作模式)

文章目录 一、Vuex1)理解vuex2)优点3)何时使用?4)使用步骤① 安装vuex② 创建vuex③ 导入vuex④ 创建仓库Store⑤ 基本使用 5)五个模块介绍1.State2.mutations3.actions4.Getter5.Modules 6)购物…

【vue】ant-col多列栅格式的表单排列方式布局异常:

文章目录 一、效果:二、解决:三、问题: 一、效果: 二、解决: 在row中添加布局类型:type“flex” 三、问题: 后期正式环境还是存在该问题 >>>.ant-form-item {max-height: 32px; }多…

【FastAPI】P1 简单实现 a+b

目录 准备工作代码运行 说明:本文通过 FastAPI 实现返回两个参数 ab 的值; 准备工作 默认读者已准备完善 Python IDE工具以及包管理工具。 首先,需要安装 fastapi 和 uvicorn 库,如果没有请使用 pip 进行安装: pip…

【Android】为什么在子线程中更新UI不会抛出异常

转载请注明来源:https://blog.csdn.net/devnn/article/details/135638486 前言 众所周知,Android App在子线程中是不允许更新UI的,否则会抛出异常: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the origin…

智慧灌区解决方案:针对典型灌区水利管理需求

​随着国家对农业水利的重视,各地积极推进智慧灌区建设,以实现对水资源的精准调度和科学化管理。下面我们针对典型灌区水利管理需求,推荐智慧灌区解决方案。 一、方案构成智慧水利解决方案- 智慧水利信息化系统-智慧水利平台-智慧水利公司 - 星创智慧水利 一、方案构成 (一)水…

安全加速SCDN是什么

安全加速SCDN(Secure Content Delivery Network,SCDN) 是集分布式DDoS防护、CC防护、WAF防护、BOT行为分析为一体的安全加速解决方案。已使用内容分发网络(CDN)或全站加速网络(ECDN)的用户&…

Java CAS原子操作过程及ABA问题

目录 一.什么是CAS 二.流程 三.缺点 四.ABA 问题 五.解决ABA问题 一.什么是CAS CAS(Compare And Swap,比较并交换),通常指的是这样一种原子操作:针对一个变量,首先比较它的内存值与某个期望值是否相同…

边缘计算AI智能分析网关V4客流统计算法的概述

客流量统计AI算法是一种基于人工智能技术的数据分析方法,通过机器学习、深度学习等算法,实现对客流量的实时监测和统计。该算法主要基于机器学习和计算机视觉技术,其基本流程包括图像采集、图像预处理、目标检测、目标跟踪和客流量统计等步骤…

EasyDarwin计划新增将各种流协议(RTSP、RTMP、HTTP、TCP、UDP)、文件转推RTMP到其他视频直播平台,支持转码H.264、文件直播推送

之前我们尝试做过EasyRTSPLive(将RTSP流转推RTMP)和EasyRTMPLive(将各种RTSP/RTMP/HTTP/UDP流转推RTMP,这两个服务在市场上都得到了比较多的好评,其中: 1、EasyRTSPLive用的是EasyRTSPClient取流&#xff…

Presents-codeforces

题目链接:Problem - 136A - Codeforces 解题思路: 这题挺有意思,大致意思是,每个人都会互相送礼物,可能送给自己,可能送给别人,第i个数表示第i个人要把礼物送给第i个数的人比如1 3 2&#xff0…

C++系列-第1章顺序结构-9-字符类型char

在线练习: http://noi.openjudge.cn/ https://www.luogu.com.cn/ 总结 本文是C系列博客,主要讲述字符类型char 字符类型char 在C编程语言中,char是一种基本的数据类型,它用于存储单个字符。字符可以是字母、数字、标点符号或者…

智慧门店:如何利用AI视频智能监管与存储技术让门店降本增效?

一、行业背景 TSINGSEE青犀视频智慧门店解决方案是一种集成了人工智能、大数据、物联网等技术的零售解决方案,目的是提高门店的运营效率、用户体验和业绩。随着数字化转型的加速,连锁门店需要跟上时代的步伐,需要利用数字化手段提高运营效率…

Android14之DefaultKeyedVector实现(一百八十二)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…