Go 语言中的字符串基本操作

这篇文章已经放到腾讯智能工作台的知识库啦,链接在这里:ima.copilot-Go 入门到入土。要是你有啥不懂的地方,就去知识库找 AI 聊一聊吧。

本篇将详细讲解 Go 语言中与字符串相关的操作。

1、rune 和 字符串长度

1、Go 函数语法约定

在开始之前,需要注意 Go 语言的一个语法规范。函数或流程控制语句的左花括号 { 必须与函数名或关键字在同一行,不能换行书写。

image.png

这种强制性规定统一了代码风格,避免了不同开发者因个人习惯造成代码格式的混乱。

2、len() 计算字符串长度

Go 语言提供了一个内置函数 len(),可以方便地计算出字符串的长度。

image.png

在上述代码中,len() 函数直接返回了字符串 name 的长度。这是一个非常便捷和常见的操作。

3、len() 的本质:字节数

len() 函数虽然通用,但它返回的是字符串所占的字节数(the number of bytes),而不是字符数。

当字符串只包含英文字母、数字或标准 ASCII 符号时,一个字符恰好占用一个字节,此时字节数等于字符数。但当字符串中包含非 ASCII 字符(如中文、日文等)时,情况就有所不同。

UTF-8 编码(Go 语言默认的字符串编码)中:

  • 一个英文字符占用 1 个字节。

  • 一个中文字符通常占用 3 个字节。

image.png

直观上看,字符串 “叫我阿杰好l” 包含 6 个字符。但 len() 的计算结果为什么是 16 呢? 因为计算的是字节数:1 (l) + 5*3 (叫我阿杰好) = 16 个字节。

4、如何获取真实的字符数?

在很多业务场景中,我们关心的是字符串实际包含多少个字符,而不是它占用了多少字节。为了解决这个问题,我们需要将字符串转换为 rune 切片。

rune 类型是 Go 语言中用于表示单个 Unicode 字符的特殊类型。将字符串转换为 []rune 后,每个中文字符和英文字符都会被当作一个独立的元素。此时再使用 len() 函数,就能得到准确的字符数量。

image.png

5、总结

在 Go 语言中计算字符串长度时,必须注意以下关键点:

  1. 如果你的字符串只包含英文或 ASCII 字符,或者你关心的就是字节长度,可以直接使用 len(str)

  2. 如果你需要知道字符串中实际的字符数量(特别是处理包含中文等多字节字符的场景),必须先将字符串转换为 rune 切片 []rune(str),然后再对其使用 len() 函数。

掌握这个细节对于正确处理多语言文本至关重要。

2、转义符详解

1、 为什么需要转义符?

假设我们需要定义一个字符串,其内容本身就包含特殊字符,例如双引号。

如果我们直接这样编写代码:

image.png

编译器会报错。因为在 Go 语言中,双引号用于界定字符串的开始和结束。上述代码会被编译器误解为:第一个字符串是 "Go ",第二个字符串是 "",而中间的 体系课 则是不合法的语法。

为了在字符串内部正确地包含双引号等特殊字符,我们就需要使用转义符。

2、使用反斜杠 \ 进行转义

在 Go 中,反斜杠 \ 是核心的转义符。当它出现在一个特殊字符前时,它会“转义”该字符,使其失去原有的特殊含义,而被当作一个普通的字符来处理。

示例:

要在一个由双引号定义的字符串中包含双引号,我们可以在内部的双引号前加上 \

image.png

在这里,\" 被编译器视为一个整体,并被解释为单个双引号字符。

2、使用反引号 ` 创建原生字符串

除了使用转义符,Go 语言还提供了一种更简洁的方式来处理包含大量特殊字符的字符串:原生字符串字面量 (Raw String Literal)。这种字符串使用反引号 ` (通常位于键盘 Tab 键的上方) 来定义。

在反引号包裹的字符串中,所有的字符都按其字面意义进行解释,无需任何转义

image.png

这种写法的输出结果与使用转义符完全相同。反引号内的内容可以随意编写,包括换行符和双引号,这与 Python 中的三引号字符串有些类似,非常适合定义多行文本或包含复杂特殊字符的文本。

3、常见的转义序列

无论是否使用原生字符串,理解并掌握常见的转义序列都至关重要。转义符 \ 可以与多个字符组合,形成具有特殊含义的序列。这些序列通常与 ASCII 控制码相对应。

以下是一些最常用的转义序列:

|序列|含义|描述|

|—|—|—|

|\n|换行符|将光标移动到下一行的开头 (Line Feed)|

|\r|回车符|将光标移动到当前行的开头 (Carriage Return)|

|\t|水平制表符|相当于按下 Tab 键,用于对齐文本|

|\\|反斜杠|在字符串中插入一个反斜杠字符 \|

|\"|双引号|在字符串中插入一个双引号字符 "|

|\'|单引号|在字符串中插入一个单引号字符 '|

|\?|问号|在字符串中插入一个问号字符 ?|

其中,\r\n 组合(回车并换行)在 Windows 系统中常被用作标准的换行符,而 \n 在 Unix/Linux 和 macOS 中更为常见。

image.png

4、fmt.Printfmt.Println 的区别

在 Go 中,标准库 fmt 提供了多种打印函数,其中 PrintPrintln 的一个关键区别在于是否自动换行。

  • fmt.Println:在打印完所有参数后,会自动在末尾添加一个换行符

  • fmt.Print:仅打印传入的参数,不会在末尾添加任何内容

image.png

如果我们想用 Print 实现与 Println 相同的换行效果,就需要手动添加转义符 \n\r\n

image.png

掌握转义符是 Go 语言编程的基础。无论是为了在字符串中嵌入特殊字符,还是为了控制输出格式,理解 \` 的用法都至关重要。在后续的开发中,我们会频繁地遇到这些概念,熟练运用它们将极大提升编码效率和代码的可读性。

3、格式化输出

在实际开发中,我们常常需要将不同类型的变量(如字符串、整数、浮点数等)组合成一个完整的字符串进行输出。

1、字符串拼接的挑战

使用简单的 + 号拼接字符串,在处理复杂或多类型数据时会变得非常繁琐且难以维护。

image.png

可以看到,这种方式不仅代码可读性差,还需要手动进行类型转换(如 strconv.Itoa),非常不便。

2、使用 fmt.Printf 进行格式化输出

为了解决上述问题,Go 语言提供了 fmt.Printf 函数。它允许我们使用一个模板字符串和一系列占位符(也称格式化动词),将变量优雅地嵌入到字符串中。

Printf 的工作方式:

  1. 定义一个包含占位符的模板字符串。

  2. 在字符串后面,按顺序提供与占位符对应的变量。

  3. 函数会自动将变量替换到相应的位置,并输出到控制台。

示例:

image.png

这段代码不仅更易读、更易维护,而且 Go 会自动处理类型,我们无需再关心 intstring 的转换。注意 Printf 不会自动换行,因此我们在模板末尾手动添加了 \n

3、生成格式化字符串:fmt.Sprintf

有时我们需要的不是直接打印到控制台,而是将格式化后的结果保存为一个字符串变量。这时可以使用 fmt.Sprintf

它的用法与 Printf 完全相同,唯一的区别是它会返回一个格式化好的字符串,而不是将其打印出来。

image.png

这个函数在构建日志信息、生成 API 响应或任何需要先处理再输出的场景中非常有用。

4、性能说明

通常情况下,fmt.Printffmt.Sprintf 是构建字符串的首选方法,因为它们极大地提升了代码的可读性和可维护性。但在对性能有极端要求的场景中,手动的字符串拼接(如使用 strings.Builder)可能会有更好的性能表现。对于绝大多数应用,可读性带来的好处远超微小的性能差异。

5、常用格式化占位符

Go 提供了丰富的占位符来控制输出格式。以下是一些最常用的占位符:

| 占位符 | 描述 | 常用类型 |

| ---------- | -------------------------------- | --------------- |

| 通用 | | |

| %v | 默认格式的值。对于不同类型,会以最合适的方式展示。 | 任何类型 |

| %+v | 在 %v 的基础上,打印结构体时会额外输出字段名。 | struct |

| %#v | Go 语法表示的值。输出结果是符合 Go 语法的字面量。 | 任何类型 |

| %T | 值的类型。输出变量的类型信息。 | 任何类型 |

| 字符串 | | string |

| %s | 普通的字符串或 []byte | string |

| %q | 为字符串加上双引号,并对特殊字符进行安全转义。 | string |

| 整数 | | int, uint 等 |

| %d | 十进制表示 | int |

| %b | 二进制表示 | int |

| %o | 八进制表示 | int |

| %x, %X | 十六进制表示 (分别为小写 a-f 和大写 A-F) | int |

| 浮点数 | | float |

| %f | 标准小数表示 (例如 123.456) | float |

| %e, %E | 科学计数法表示 (例如 1.23456e+02) | float |

| 布尔值 | | bool |

| %t | truefalse | bool |

| 指针 | | 指针类型 |

| %p | 指针的十六进制表示(以 0x 开头) | 指针 |

宽度与对齐示例:

你还可以控制输出的宽度和对齐方式。

image.png

掌握格式化输出是 Go 语言开发者的必备技能。fmt.Printffmt.Sprintf 提供了一种强大而灵活的方式来构建和展示字符串,使得代码更加简洁和专业。在日常开发中,应优先选择这些函数来处理字符串格式化任务。

4、高性能字符串拼接

当需要拼接大量字符串,尤其是在循环中,性能就成为一个重要的考量因素。此时,strings.Builder 是最佳选择。它的性能远高于 + 拼接和 fmt.Sprintf

strings.Builder 通过维护一个内部的字节缓冲区(buffer)来避免每次拼接都重新分配内存,从而实现高效的字符串构建。

使用步骤:

  1. 创建一个 strings.Builder 实例。

  2. 使用 WriteString()Write() 等方法向其内部缓冲区追加内容。

  3. 最后调用 String() 方法获取最终拼接完成的字符串。

image.png

虽然 strings.Builder 的代码看起来比 Sprintf 繁琐一些,但在性能敏感的场景下,它是构建字符串的不二之选。

如何选择拼接方式

掌握不同场景下最合适的字符串拼接方法,是编写高效、可维护 Go 代码的关键。

  • + 拼接:仅适用于少量、简单的字符串连接。

  • fmt.Sprintf日常开发首选。代码可读性最高,使用最方便,足以应对绝大多数场景。

  • strings.Builder性能要求高的场景首选。当程序中有大量或频繁的字符串拼接操作(例如在循环内部)时,应优先使用 Builder 以获得最佳性能。

5、字符串的比较

在 Go 中,比较字符串是一项直接且常用的操作。

1、等于 (==) 和不等于 (!=)

你可以使用标准的比较运算符 ==!= 来判断两个字符串是否完全相同。

image.png

2、大于 (>) 和小于 (<)

Go 语言同样支持使用 ><>=<= 来比较字符串的大小。

比较规则: 字符串的比较是按字典顺序进行的。它会从左到右逐个比较两个字符串中对应位置字符的 ASCII 码值(或更准确地说是 Unicode 码点)。一旦发现差异,比较立即结束并返回结果。

image.png

6、字符串操作常用方法

Go 的标准库 strings 提供了大量实用、高效的字符串处理函数。要使用它们,首先需要导入该包:


import ("strings")

下面我们介绍一些最常用的函数。

1、包含与计数

  • strings.Contains(s, substr): 判断字符串 s 中是否包含子串 substr

  • strings.Count(s, substr): 计算子串 substr 在字符串 s 中出现的次数。

image.png

2、分割与连接

  • strings.Split(s, sep): 使用分隔符 sep 将字符串 s 分割成一个字符串切片。

image.png

如果分隔符不存在,Split 会返回一个只包含原字符串的切片。

3、前缀与后缀

  • strings.HasPrefix(s, prefix): 判断字符串 s 是否以 prefix 开头。

  • strings.HasSuffix(s, suffix): 判断字符串 s 是否以 suffix 结尾。

image.png

4、查找位置

  • strings.Index(s, substr): 查找子串 substr 在字符串 s 中首次出现的位置(字节索引)。如果不存在,则返回 -1。

image.png

注意Index 返回的是字节位置。对于包含多字节字符(如中文)的字符串,这个位置可能不等于字符的个数。

5、替换

  • strings.Replace(s, old, new, n): 将字符串 s 中的 old 子串替换为 new。参数 n 控制替换次数:

  • n < 0 (通常用 -1): 全部替换。

  • n > 0: 最多替换 n 次。

image.png

6、大小写转换

  • strings.ToLower(s): 将字符串转换为全小写。

  • strings.ToUpper(s): 将字符串转换为全大写。

image.png

image.png

7、修剪字符

  • strings.Trim(s, cutset): 从字符串 s 的两端移除 cutset 中包含的任意字符。

  • strings.TrimSpace(s): 移除字符串两端的空白字符(空格、制表符、换行符等),这是最常用的修剪函数。

  • strings.TrimLeft(s, cutset)strings.TrimRight(s, cutset): 分别只从左边或右边修剪。

image.png

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

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

相关文章

数学建模会议笔记

看似优化模型 建立整数规划模型 用优化软件、启发式方法、精确方法求解 建立图论和组合优化模型用组合优化方法、启发式方法求解 建立博弈论模型 数据统计分析与可视化- 数据拟合、参数估计、插值、数据的标准化、去伪补全相关度分析、分类、聚类等 最优化理论和方法 线性规划…

学习昇腾开发的六天--ACL应用开发之运行第一个实例

1、下载一个实例&#xff0c;运行一个图像分类实例&#xff08;环境&#xff1a;Ubuntu22.04&#xff0c;硬件&#xff1a;昇腾310B1&#xff0c;加速模块&#xff1a;atlas 200i a2&#xff09; samples: CANN Samples - Gitee.com 目录结构如下&#xff1a; ├── data │…

可灵AI-快手公司自主研发的一款AI视频与图像生成工具

可灵AI是由快手公司自主研发的一款AI视频与图像生成工具&#xff0c;于2024年6月正式推出。以下是对其的详细介绍&#xff1a; 核心功能 AI视频生成&#xff1a; 文生视频&#xff1a;输入文字描述&#xff0c;AI可自动生成匹配的视频片段。图生视频&#xff1a;上传图片&…

创客匠人解析:存量时代创始人 IP 打造与免费流量池策略

在存量竞争的商业环境中&#xff0c;企业如何突破增长瓶颈&#xff1f;创客匠人结合新潮传媒创始人张继学的实战洞察&#xff0c;揭示 “品牌 IP” 双轮驱动下的免费流量池构建逻辑&#xff0c;为知识变现与创始人 IP 打造提供新思路。 一、存量时代的流量革命&#xff1a;从…

提升语义搜索效率:LangChain 与 Milvus 的混合搜索实战

我从不幻想人生能够毫无波折&#xff0c;但我期望遭遇困境之际&#xff0c;自身能够成为它的克星。 概述 LangChain与Milvus的结合构建了一套高效的语义搜索系统。LangChain负责处理多模态数据&#xff08;如文本、PDF等&#xff09;的嵌入生成与任务编排&#xff0c;Milvus作…

MySQL配置简单优化与读写测试

测试方法 先使用sysbench对默认配置的MySQL单节点进行压测&#xff0c;单表数据量为100万&#xff0c;数据库总数据量为2000万&#xff0c;每次压测300秒。 sysbench --db-drivermysql --time300 --threads10 --report-interval1 \--mysql-host192.168.0.10 --mysql-port3306…

猎板深耕透明 PCB,解锁电子设计新边界

在电子技术快速迭代的当下&#xff0c;猎板始终关注行业前沿&#xff0c;透明 PCB 作为极具创新性的技术&#xff0c;正在改变电子设备的设计与应用格局。​ 从传统的绿色、棕色 PCB 到如今的透明 PCB&#xff0c;其突破在于特殊基材与导电材料的运用&#xff0c;实现 85%-92%…

FLAML:快速轻量级自动机器学习框架

概述 FLAML&#xff08;Fast and Lightweight AutoML&#xff09;是微软开发的一个高效的自动机器学习&#xff08;AutoML&#xff09;框架。它专注于在有限的计算资源和时间约束下&#xff0c;自动化机器学习管道的构建过程&#xff0c;包括特征工程、模型选择、超参数调优等…

Github 以及 Docker的 wsl --list --online无法访问问题

修改电脑DNS 腾讯 DNS IP&#xff1a;119.29.29.29 备用&#xff1a;182.254.116.116 阿里DNS IP&#xff1a;223.5.5.5 223.6.6.6 百度DNS IP:180.76.76.76 谷歌DNS IP:8.8.8.8

Go 语言中的变量和常量

这篇文章已经放到腾讯智能工作台的知识库啦&#xff0c;链接在这里&#xff1a;ima.copilot-Go 入门到入土。要是你有啥不懂的地方&#xff0c;就去知识库找 AI 聊一聊吧。 1、变量的声明与使用 我们来探讨编程语言中最核心的概念之一&#xff1a;变量。 1、静态语言中的变量…

破局传统订货!云徙渠道订货系统赋能企业数字化渠道升级

在数字化浪潮的推动下&#xff0c;传统经销商订货模式面临着诸多挑战&#xff0c;如信息孤岛、系统崩溃、移动化不足等问题。云徙渠道订货系统凭借其创新的数字化架构和强大的功能模块&#xff0c;正在成为企业实现渠道数字化转型的重要工具。 系统功能与创新 云徙渠道订货系统…

SQL关键字三分钟入门:UNION 与 UNION ALL —— 数据合并全攻略

在处理数据时&#xff0c;有时我们需要将来自不同表或同一表的不同查询结果合并在一起。例如&#xff1a; 合并两个部门的员工名单&#xff1b;将多个地区的销售数据汇总&#xff1b;显示某段时间内所有新增和修改的记录。 这时候&#xff0c;我们就需要用到 SQL 中非常强大的…

SNMPv3 的安全命名空间详解

1. 安全命名空间的本质 安全命名空间是 SNMPv3 的核心安全机制&#xff0c;通过 上下文&#xff08;Context&#xff09; 实现&#xff1a; #mermaid-svg-6cV9146nTFF1zCMJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#merma…

【嵌入式硬件实例】-555定时器实现烟雾和易燃气体泄露检测

555定时器实现烟雾和易燃气体泄露检测 文章目录 555定时器实现烟雾和易燃气体泄露检测1、555定时器介绍2、MQ-2 气体/烟雾传感器模块介绍3、硬件准备与接线在本文中,我们将使用555定时器和MQ-2气体传感器构建一个气体泄漏检测和报警系统。它在煤气泄漏期间用作家庭安全警报器。…

【机器人】DualMap 具身导航 | 动态场景 开放词汇语义建图 导航系统

DualMap 是一个在线的开放词汇语义映射系统&#xff0c;使得机器人能够通过自然语言查询在动态变化的环境中理解和导航 双地图导航&#xff0c;结合全局抽象地图进行高层次候选选择&#xff0c;以及局部具体地图进行精确目标定位&#xff0c;有效管理和更新环境中的动态变化。…

【Fifty Project - D37】

fifty project算是失败了一半了 成功的那一半在于一定程度上拯救了我的作息和健康&#xff0c;两个月前入职体检的肝有点不健康&#xff0c;昨天复查发现全都回到了健康范围&#xff01;尿酸也在正常范围&#xff01;就是体重还是没减下来hhh 失败的一半在于自己很差劲的规划能…

解码危险品物流背后的“隐形防线”

当急救药品跨越千里送达医院&#xff0c;当新能源电池准时抵达生产线&#xff0c;当化工原料安全运往工厂……这些与日常生活息息相关的场景背后&#xff0c;有一群人始终在和时间赛跑&#xff0c;与风险博弈。他们不是超级英雄&#xff0c;而是危险品物流从业者——一个鲜少被…

Flutter Melos在外包团队协作中的弊端与应对策略

引言 在大型Flutter项目开发中&#xff0c;Melos作为一款优秀的Monorepo管理工具&#xff0c;能够有效协调多包项目的开发流程。然而&#xff0c;当项目涉及外包团队协作时&#xff0c;Melos的使用会面临一系列独特的挑战。本文将深入分析Flutter Melos在外包团队协作环境中的…

<selectKey> 中的order 属性

在 MyBatis 中&#xff0c;<selectKey> 标签的 order 属性用于指定生成主键值的 SQL 语句执行时机。 除了 AFTER&#xff0c;MyBatis 还支持另一种模式&#xff1a;BEFORE&#xff0c; 它们有明确的使用场景和区别&#xff1a; order"AFTER" 适用数据库&#x…

BitsAndBytes(简称 BnB)是一个用于“压缩”大语言模型的工具包

BitsAndBytes&#xff08;简称 BnB&#xff09;是一个用于“压缩”大语言模型的工具包&#xff0c;能把模型从原来的16位或32位&#xff0c;压成4位或8位&#xff0c;减少显存占用&#xff0c;同时保持尽量高的精度。 &#x1f9e9; 为什么叫 Bits and Bytes&#xff1f; 它的…