go字符串详解

2023-11-19


摘要

go字符串结构体包含:指向底层存储数组的指针、字符串长度。字符串按utf-8将字符编码成二进制数,然后存储在byte数组中。因为utf-8编码一个字符可能占用多个字节,例如一个汉字占3个字节,所以字符串中的一个字符可能对应byte数组中的多个元素。为了让一个字符对应数组的一个元素以便于处理,go设计了rune类型,其底层是int32,四个字节,正好能存储最大四个字节utf-8编码数据。

1、byte和rune类型

  • byte等价于uint8类型的数据,一个字节大小,是字符串底层存储数据的结构。
  • rune等价于int32类型的数据,四个字节大小,为了处理utf-8字符串而设计的。因为go语言字符串默认是按照utf-8编码的方式存储数据的,其中最大的字符占用4个字节的数据,所以需要rune才能一个字符对应一个数据元素。

2、字符串(string)

在go中字符串具有如下特征:

  • go字符串存储在只读内存段中,不能被修改,但可以被切片和复制。
  • 字符串结构由一个指向底层数组的指针和字符串长度组成。因为给出了具体长度,所以不需要以’\0’的方式判断字符串结尾。
  • 底层使用字节(byte)数组存储字符串中各字符对应的数字编码。一个字符可能占用好几个byte。

需要注意的是在utf-8编码中,一个汉字占用3个字节,而byte是uint8类型,一个byte元素一个字节,需要三个byte才能存储一个汉字。所以:

func main() {
   s := "哈喽世界"
   fmt.Println(len(s)) // 输出:12
}

而rune是int32类型,四个字节,和utf-8最大字节数(4个字节)一致,所以可以将string类型转换为rune,去查看其具体存储的字符数。如下:

func main() {
   s := "哈喽世界"
   fmt.Println(len([]rune(s))) // 输出:4
}

需要注意的是:go中rune类型就是为了处理utf-8字符串而设计的,而定长4字节的方式存储utf-8中只占1、2、3个字节的字符,存在一定的空间浪费。所以string默认是按照byte类型的存储的,更加节省空间,当需要的时候,再转换为rune处理。

3、练习-反转字符串

如果反转函数如下:

func reverse(s string) string {
   bs := []byte(s)
   sLen := len(bs)
   for i := 0; i < sLen/2; i++ {
      bs[i], bs[sLen-i-1] = bs[sLen-i-1], bs[i]
   }
   return string(bs)
}

那么传入属于1字节编码的ASCILL字符,能够被反转:

func main() {
   s := "abcdefg"
   fmt.Println(reverse(s)) // 输出gfedcba
}

但是若传入需要占用多个字节的字符,就会输出乱码:

s := "哈喽世界"
fmt.Println(reverse(s)) // 输出��疸佖刓�

所以如果想要使得所有输入字符都能被正确的反转,应该使用rune代替byte:

func reverse(s string) string {
   bs := []rune(s)
   sLen := len(bs)
   for i := 0; i < sLen/2; i++ {
      bs[i], bs[sLen-i-1] = bs[sLen-i-1], bs[i]
   }
   return string(bs)
}

func main() {
   s := "哈喽世界"
   fmt.Println(reverse(s)) // 输出:界世喽哈
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go字符串详解 的相关文章

  • golang-bufio 缓冲扫描

    前面两篇博客 介绍了 bufio 包中的缓冲读和写 bufio go 下面再来介绍一下缓冲扫描 scan go 这个扫描的是用来对缓存读的更高级封装 提供了一些更易用的方法 缓冲扫描 Scanner 提供了一个方便的接口来读取数据 例如使用
  • golang基础教程

    目录 golang基础教程 一 环境搭建 golang基础教程 二 开发规范及API golang基础教程 三 变量与数据类型概述 golang基础教程 四 基本数据类型 golang基础教程 五 基本数据类型的转换 golang基础教程
  • Go Web编程实战(6)----反射

    目录 反射 反射的3大原则 接口类型变量 转换为 反射类型对象 反射类型对象 转换为 接口类型变量 反射类型对象 修改 值必 可写的 反射 与其他语言一样 Go语言的反射同样是指 计算机程序在运行时 可以访问 检测和修改它本身状态或行为的一
  • Jenkins系列:3、wsl/ubuntu安装Jenkins及Jenkins构建可交叉编译的go程序

    Jenkins系列 3 wsl ubuntu安装Jenkins及Jenkins构建可交叉编译的go程序 文章目录 Jenkins系列 3 wsl ubuntu安装Jenkins及Jenkins构建可交叉编译的go程序 1 前言 2 wsl
  • 【golang】error parsing regexp: invalid or unsupported Perl syntax (正则表达式校验密码)

    要在 Go 中编写密码校验规则 确保密码不少于8位且包含数字和字母 你可以使用正则表达式和 Go 的 regexp 包来实现 以下是一个示例代码 错误示范 package main import fmt regexp func valida
  • Golang协程与通道整理

    协程goroutine 不由OS调度 而是用户层自行释放CPU 从而在执行体之间切换 Go在底层进行协助实现 涉及系统调用的地方由Go标准库协助释放CPU 总之 不通过OS进行切换 自行切换 系统运行开支大大降低 通道channel 并发编
  • Golang三剑客之Pflag、Viper、Cobra

    如何构建应用框架 想知道如何构建应用框架 首先你要明白 一个应用框架包含哪些部分 在我看来 一个应用框架需要包含以下 3 个部分 命令行参数解析 主要用来解析命令行参数 这些命令行参数可以影响命令的运行效果 配置文件解析 一个大型应用 通常
  • Go 语言注释教程

    注释是在执行时被忽略的文本 注释可用于解释代码 使其更易读 注释还可用于在测试替代代码时防止代码执行 Go支持单行或多行注释 Go单行注释 单行注释以两个正斜杠 开头 在 和行尾之间的任何文本都将被编译器忽略 不会被执行 示例 This i
  • 有哪些不错的 Golang 开源项目?

    目前人在字节做 Go 开发 寻找 Golang 开源项目学习目的可能是 想学习或者提高自己对 Go 项目的组织和编排能力 想学习 Go 项目的框架设计 想在一些 Go 语法上细节的优化和进阶 我推荐两个项目 一 tinode 这是一个开源的
  • go-zero 开发入门-加法客服端示例

    定义 RPC 接口文件 接口文件 add proto 的内容如下 syntax proto3 package add 当 protoc gen go 版本大于 1 4 0 时需加上 go package 否则编译报错 unable to d
  • go-zero 的 etcd 配置

    实现代码在 core discov config go 文件中 type EtcdConf struct Hosts string Key string ID int64 json optional User string json opt
  • go-zero开发入门-API网关鉴权开发示例

    本文是 go zero开发入门 API网关开发示例 一文的延伸 继续之前请先阅读此文 在项目根目录下创建子目录 middleware 在此目录下创建文件 auth go 内容如下 鉴权中间件 package middleware impor
  • GoLong的学习之路,进阶,微服务之序列化协议,Protocol Buffers V3

    这章是接上一章 使用 RPC包 序列化中没有详细去讲 因为这一块需要看的和学习的地方很多 并且这一块是RPC中可以说是最重要的一块 也是性能的重要影响因子 今天这篇主要会讲其使用方式 文章目录 Protocol Buffers V3 背景以
  • 【go语言】error错误机制及自定义错误返回类型

    简介 Go 语言通过内置的 error 接口来处理错误 该接口定义如下 type error interface Error string 这意味着任何实现了 Error 方法的类型都可以作为错误类型 在 Go 中 通常使用 errors
  • [每周一更]-(第55期):Go的interface

    参考地址 https juejin cn post 6978322067775029261 https gobyexample com interfaces https go dev tour methods 9 介绍下Go的interfa
  • Golang拼接字符串性能对比

    g o l a n g golang g o l an g
  • 这套Go语言开发框架组合真的非常高效

    我尝试过很多框架 从Django Flask和Laravel到NextJS和SvelteKit 到目前为止 这是我唯一可以使用的不会让我感到疯狂或者放弃项目的堆栈 框架 我喜欢所有这些框架 但我只是不太适应它们的设计方式 实际上 我是一个弱
  • go cannot find package “github.com/gorilla/websocket“解读

    Go无法找到包 github com gorilla websocket 的解决方案 在Go开发过程中 我们经常会依赖第三方库来简化开发工作 而使用 go get 命令安装这些库时 有时候我们可能会遇到类似于以下错误的情况 plaintex
  • 【go语言】结构体数据填充生成md错误码文件

    这里使用pongo2这个模版引擎库进行md文件渲染 GitHub flosch pongo2 Django syntax like template engine for Go package main import fmt github
  • 【go语言】AST抽象语法树详解&实践之扫描代码生成错误码文档

    背景 为了能识别出代码中抛出错误码的地址和具体的错误码值 再根据错误码文件获取到错误码的具体值和注释 方便后续的排错 这里使用AST进行语法分析获取到代码中的目标对象 一 编译过程 在开始解析代码之前先补充了解一下编译过程 编译过程是将高级

随机推荐

  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • ESP32C3 移植ST7735 LVGL

    关于lvgl LVGL是一个C语言编写的免费的开源图形库 其提供了用于嵌入式GUI的各种元素 用户可以利用丰富的图形库资源 在消耗极低内存的情况下构建视觉效果丰富多彩的GUI 只需 64kB 闪存和 8kB RAM 就足以满足简单的用户界面
  • vue构建路由,报错Cannot read properties of undefined (reading ‘forEach‘)

    构建vue路由 这个foreach报错 意味着有一个进入循环的值为null 如果看了其他文章的标准还没有解决的话 建议加一个routes constantRoutes 即在定义router时手动加上一个routes属性 完整的代码 App
  • Linux 如何设置开机自启动脚本

    Linxu开机自启动脚本 一 CentOS系统和Redhat系统如下 1 修改 etc rc d rc local为 bin bash THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES It is
  • Android开发-在Android应用里接入AdMob广告进行变现的实现

    前 言 前段时间 自己开发了一款个人的Android应用想上线 但是由于国内的应用商城对个人开发者不是很友好 即使应用已经申请了软件著作权了也不能上线的了 有些应用只能以企业的名义来上线不能以个人的名义来上线 如影视类 新闻资讯类的应用 无
  • 遇见VS,scanf中_s不能少,要不然Bug报到家,如何解决这个问题呢?

    相信大家第一次用VS时 都会遇到这样的问题 VS莫名其妙的跟你说要用scanf s 使用scanf这个函数不安全 这里说一下为什么我们要用scanf而不使用它推荐的scanf s 我们写代码总不能是写给自己看吧 我们要写的代码可能是要发给别
  • Nginx基础03:配置文件nginx.conf(Part2)

    上一篇文章概述与罗列了 全局配置块 events配置块 http全局块 的基本配置与属性 本篇文章将继续深入server块的配置项 以及相关应用 上篇文章地址 Nginx基础02 配置文件nginx conf Part1 如何使用本篇文章
  • webpack代码混淆

    作者 桑榆 QQ 934440653 有问题 评论留言 或qq联系 安装 npm install save dev webpack obfuscator 属性 compact true 压缩 无换行 controlFlowFlattenin
  • 网络安全体系方法论

    安全牛整合多位资深安全顾问的一线咨询经验 首次公开发布 网络安全体系方法论 旨在给企业或机构提供一个最佳实践的参考 以帮助企业真正提升对网络安全工作的认识 并在安全建设和运营中不断成长 本架构方法论参考了NIST Cybersecurity
  • 什么是流程图

    什么是流程图 流程图是对过程 算法 流程的一种图像表示 在技术设计 交流及商业简报等领域有广泛的应用 通常用一些图框来表示各种类型的操作 在框内写出各个步骤 然后用带箭头的线把它们连接起来 以表示执行的先后顺序 用图形表示算法 直观形象 易
  • How does double arrow (=>) operator work in Perl?

    原文链接 https stackoverflow com questions 4093895 how does double arrow operator work in perl The use of the gt operator ca
  • Ant Design Pro从零到一(认识AntD)

    废话 在我们第一次接触AntD的时候 会遇到两个东西 一个是Ant Design 另一个是Ant Design Pro 他们的官网分别是 Ant Design 一套企业级 UI 设计语言和 React 组件库 Ant Design Pro
  • 商品期货策略-ATR通道突破策略

    实现平台 BigQuant 人工智能量化投资平台 可在文末前往原文一键克隆代码进行进一步研究 导语 商品期货交易上线啦 听闻这个消息的小编当然坐不住了 决定立刻商品期货走一波 本文选择实现的是经典的ATR通道突破策略 也被称为波动性突破策略
  • C++——详解类模板与友元函数

    纵有疾风起 人生不言弃 本文篇幅较长 如有错误请不吝赐教 感谢支持 文章目录 类模板与友元函数 1 非模板友元函数 2 约束模板友元函数 3 非约束模板友元函数 类模板与友元函数 模板类的友元函数有三类 1 非模板友元函数 友元函数不是模板
  • 【2023秋招面经】深信服 前端 一面(1h)

    自我介绍 项目比较有难度的地方 你刚刚说Vue3按功能来组合 不是按Option API组合 你简单写一下伪代码 实现一个计时器 进入这个模块计时器开始计时 离开页面则销毁 在中间过程中 获取计时的时间 function useTime 实
  • JavaScript动态生成表格

    源代码
  • 修改 TeamViewer ID 的方法:

    TeamViewer 使用频繁后会被判定为商业用途 不可用 此软件的账号和设备mac地址绑定 修改TeamViewer ID后可以重新开始使用 下述方法可以成功修改TeamViewer ID 关闭TeamViewer 开始 gt 运行 录入
  • element-table新增 以input框形式输入

    工作遇到的问题记录下 代码如下 选了其中一行做例子
  • 好用的在线画图工具processon

    ProcessOn是一款基于SaaS的前沿 高效线上作图工具 它将Visio Xmind等专业作图工具搬到了 云端 注册链接 https www processon com i 564bf42ce4b0a080c6d1b18f 保存 分享都
  • go字符串详解

    文章目录 摘要 1 byte和rune类型 2 字符串 string 3 练习 反转字符串 摘要 go字符串结构体包含 指向底层存储数组的指针 字符串长度 字符串按utf 8将字符编码成二进制数 然后存储在byte数组中 因为utf 8编码