【Rust自学】8.4. String类型 Pt.2:字节、标量值、字形簇以及字符串的各类操作
8.4 String类型 Pt.2字节、标量值、字形簇以及字符串的各类操作8.4.0. 本章内容第八章主要讲的是 Rust 中常见的集合。Rust 提供了很多集合类型的数据结构这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。第八章中的集合是存储在堆内存上而非栈内存上的这也意味着这些集合的数据大小无需在编译时就确定在运行时它们可以动态地变大或变小。本章主要会讲三种集合Vector、String本文和 HashMap。8.4.1. 不能使用索引来访问StringRust 中的String不同于其他语言不能用索引访问。如下例fn main() { let s String::from(6657 up up); let a s[0]; }输出error[E0277]: the type str cannot be indexed by {integer} -- src/main.rs:3:15 | 3 | let a s[0]; | ^ string indices are ranges of usize | help: the trait SliceIndexstr is not implemented for {integer} note: you can use .chars().nth() or .bytes().nth() for more information, see chapter 8 in The Book: https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings note: required for String to implement Index{integer}报错说明String类型无法使用整数来进行索引。继续往下看可以看到String没有实现Index{integer}这个 trait。8.4.2.String类型的内部表示String是对Vecu8的包装其中u8表示字节。我们可以通过String上的len()方法来返回字符串的长度。如下例fn main() { let len String::from(Niko).len(); println!({}, len); }输出4这个字符串采用的是UTF-8编码len的值为4也就是这个字符串占了 4 个字节。所以在这个例子里每个字母占用了一个字节。但情况并不总是这样。比如说我们把字符串换成其他语言这里是西里尔字母写的俄语fn main() { let hello String::from(Здравствуйте); println!({}, hello.len()); }如果你数一下这个字符串会发现有 12 个字母但是输出却是24也就是说在这个语言里面一个字母会占用两个字节中文是一个汉字占三个字节。这里所说的“字母”用专业术语表示就是Unicode 标量值而这里的每个西里尔字母都对应两个字节。通过这个例子你可以发现对String做数字索引并不总能对应到一个完整的 Unicode 标量值因为有的标量值会占不止一个字节而数字索引一次只能读到一个字节。再举个例子西里尔字母З对应两个字节这两个字节的值分别是 208 和 151。假如数字索引是允许的那么取Здравствуйте的索引0就会得到208而单独的208是没有意义的因为它缺少组成一个 Unicode 标量值所需的第二个字节。所以为了避免这种无法立即发现的 bugRust 禁止了对String使用数字索引从而在开发早期就杜绝可能的误解。8.4.3. 字节、标量值、字形簇Rust 中有三种看待字符串的方式字节、标量值和字形簇。其中字形簇最接近我们通常所说的“字母”。1. 字节看个例子fn main() { let s String::from(नमस्ते); // 天城文书写的印地语 for b in s.bytes() { print!({} , b); } }这段天城文字符串看起来好像有 4 个字母。我们使用.bytes()方法来获得它所对应的字节。输出如下224 164 168 224 164 174 224 164 184 224 165 141 224 164 164 224 165 135这 18 个字节就是计算机存储该字符串的样子。2. 标量值我们再来以 Unicode 标量值的形式来看待它fn main() { let s String::from(नमस्ते); for b in s.chars() { print!({} , b); } }使用.chars()方法能够获得这段字符串所对应的标量值。输出如下न म स ् त े它有 6 个标量值其中有些是组合标记而不是独立的字母。它们只有和前面的字符组合在一起才有意义。这也解释了为什么这段天城文字符串占 18 个字节6 个标量值每个占 3 个字节6 × 3 18 个字节。3. 字形簇因为从String里获得字形簇很复杂所以 Rust 标准库没有提供这个功能这里也就不做演示但你可以从 crates.io 找第三方 crate 来实现这个功能。总之如果这串字符串以字形簇的形式打印出来会是这样8.4.4. 为什么String不能被索引数字索引取出来的值可能并不完整无法组成一个完整的 Unicode 标量值从而导致无法第一时间察觉的错误。索引操作理应消耗常量时间也就是O(1)而String无法保证这一点要找到第n个字符必须从字符串开头向后扫描因为每个字符占用的字节数可变。8.4.5. 切割String可以使用[]在里面填上范围来创建字符串切片。关于字符串切片的详细内容见 4.5. 切片Slice。如下例fn main() { let hello String::from(Здравствуйте); let s hello[0..4]; println!({}, s); }刚才也说了一个西里尔字母占两个字节。这里的字符串切片切的是字符串的前 4 个字节也就是前两个字母。输出是Зд那如果字符串切片切的是前三个字节呢也就意味着切片的内容会是第一个字母加上半个第二个字母。这种情况会怎么样呢看下面的例子fn main() { let hello String::from(Здравствуйте); let s hello[0..3]; println!({}, s); }输出thread main panicked at src/main.rs:3:19: end byte index 3 is not a char boundary; it is inside д (bytes 2..4 of string) note: run with RUST_BACKTRACE1 environment variable to display a backtrace程序触发了panic!错误信息是结束字节索引3不是一个char边界。也就是说切割时必须沿着char的边界来切割对于西里尔字母来说就是按两个字节为单位切割。8.4.6. 遍历String对于标量值使用.chars()方法。如下例fn main() { let s String::from(नमस्ते); for b in s.chars() { print!({} , b); } }对于字节使用.bytes()方法。如下例fn main() { let s String::from(नमस्ते); for b in s.bytes() { print!({} , b); } }对于字形簇标准库未提供方法但可以使用第三方 crate。

相关新闻

【Rust自学】8.5. HashMap Pt.1:HashMap的定义、创建、合并与访问

【Rust自学】8.5. HashMap Pt.1:HashMap的定义、创建、合并与访问

8.5 HashMap Pt.1:HashMap的定义、创建、合并与访问 8.5.0. 本章内容 第八章主要讲的是 Rust 中常见的集合。Rust 提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而…

2026/10/7 9:32:56 阅读更多 →
腺相关病毒载体构建伯远生物腺相关病毒载体

腺相关病毒载体构建伯远生物腺相关病毒载体

腺相关病毒载体构建伯远生物腺相关病毒载体 伯远生物是国家级专精特新小巨人企业,国家级重点实验室,牵头多项省部级重大专项,公司科研技术人员500(硕博占比40%以上),作为功能基因研究综合性平台&#xff0c…

2026/10/12 14:32:54 阅读更多 →
办公自动化专用 OpenClaw 部署教程,内置全套运行组件(含安装包)

办公自动化专用 OpenClaw 部署教程,内置全套运行组件(含安装包)

Windows 平台 OpenClaw 部署实操|短时搭建本地 AI 智能体,简化环境配置流程 内容核心 图形化操作界面|自动化环境适配|内置完整运行组件|28 万 Tokens 资源额度|多系统兼容适配 适配版本:Open…

2026/10/17 0:38:02 阅读更多 →

最新新闻

UltraEdit v18.0 注册机失效后,如何用 TaoToken 统一 Key 管理编辑器 AI 插件

UltraEdit v18.0 注册机失效后,如何用 TaoToken 统一 Key 管理编辑器 AI 插件

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 9:36:31 阅读更多 →
Graphormer 实战:结构编码、SPD 缓存与图级别训练避坑指南

Graphormer 实战:结构编码、SPD 缓存与图级别训练避坑指南

简介:Graphormer 是论文《Do Transformers Really Perform Bad for Graph Representation?》的官方实现,面向图神经网络与图表示学习方向的研究者、算法工程师及需要复现图 Transformer 实验的学生。它通过多种结构编码把图的拓扑信息有效注入标准 Tran…

2026/10/18 9:36:31 阅读更多 →
最权威的Skills编写指南来了!33页,Anthropic亲自发布,TaoToken带你逐页拆解

最权威的Skills编写指南来了!33页,Anthropic亲自发布,TaoToken带你逐页拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 9:36:31 阅读更多 →
PPIO 一天下架多款大模型后,开发者如何用 TaoToken 统一 Key 防 API 断供

PPIO 一天下架多款大模型后,开发者如何用 TaoToken 统一 Key 防 API 断供

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 9:36:31 阅读更多 →
Brave浏览器源码编译实战:从环境搭建到定制拦截规则

Brave浏览器源码编译实战:从环境搭建到定制拦截规则

简介:Brave浏览器是一款以隐私保护和高效浏览为核心的开源网络浏览器,覆盖MacOS、Windows、Linux及Android多平台,适合关注在线安全、希望摆脱广告干扰的技术爱好者与普通用户。资源包共52个文件,约145KB,以JavaScript…

2026/10/18 9:36:31 阅读更多 →
SECS/GEM 通信协议详解:从消息结构到状态机与事件报告

SECS/GEM 通信协议详解:从消息结构到状态机与事件报告

简介:这份资源围绕半导体制造领域通用的SECS/GEM通信协议展开,面向半导体设备开发、MES系统集成及自动化测试方向的工程师与学习者,帮助理解设备与主机之间的通信机制与行为模型。内容涵盖SECS-I、SECS-II的物理层、链路层与应用层协议&#…

2026/10/18 9:35:31 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →