内容来自杨旭老师 Rust编程语言入门教程(Rust语言/Rust权威指南配套)【已完结】
第8章 通用集合类型
使用动态数组(Vector)存储多个值
创建动态数组
更新动态数组
销毁动态数组时也会销毁其中的元素
读取动态数组中的元素
遍历动态数组中的值
使用枚举来存储多个类型的值
使用字符串存储UTF-8编码的文本
字符串是什么
创建一个新的字符串
更新字符串
字符串索引
字符串切片
遍历字符串的方法
字符串的确没那么简单
使用哈希映射中存储键值对
创建一个新的哈希映射
哈希映射与所有权
访问哈希映射中的值
更新哈希映射
哈希函数
第9章 错误处理
不可恢复错误与panic!
使用panic!产生的回溯信息
可恢复错误与Result
匹配不同的错误
失败时触发panic的快捷方式:unwrap和expect
传播错误
要不要使用panic!
示例、原型和测试
当你比编译器拥有更多信息时
错误处理的指导原则
创建自定义类型来进行有效性验证
!!!











!!!

!!!
在 Rust 中,OsString、OsStr、CString 和 CStr 都是用于处理不同类型的字符串和字符序列的类型。
OsString和OsStr:OsString是一个可拥有不同平台原生字符串表示的可变字符串类型。它可以包含任意有效的 Unicode 字符序列,并且可以自动适应不同的操作系统。OsStr是一个不可变的字符串切片类型,它对应于OsString。它提供了对OsString中存储的字符串进行引用的功能。
这些类型的目的是为了在操作系统之间提供一致的字符串处理,以便在不同平台上编写可移植的代码。
CString和CStr:CString是一个在 Rust 中表示以 null 字节结尾的 C 字符串的类型。它是一个可拥有不同平台原生字符串表示的可变字符串类型,类似于OsString。它提供了将 Rust 字符串转换为 C 字符串的功能。CStr是一个在 Rust 中表示以 null 字节结尾的不可变 C 字符串的类型。它对应于CString,提供了对CString中存储的 C 字符串进行引用的功能。
这些类型主要用于与 C 代码进行交互,特别是在调用 C 函数或与 C 库进行交互时,需要将 Rust 字符串转换为 C 字符串或引用 C 字符串。
通过使用这些类型,Rust 提供了灵活且安全地处理不同类型的字符串和字符序列的功能,同时也支持与操作系统和 C 代码的交互。
Rust中 使用push_str和+ 连接字符串有何区别?哪个性能更好
Rust中有两种主要方式来连接字符串:
使用
push_str方法在一个现有的String上追加另一个字符串。使用
+操作符连接两个字符串生成一个新的String。
两者的主要区别在于:
push_str直接在原字符串上修改,不需要重新分配内存。这样更加高效,特别是在追加多个字符串的时候。+操作符会重新分配内存并复制字符串内容,生成一个新的String。这在连接少量字符串时可以接受,但连接大量字符串会产生很多无用的内存分配和数据复制。
所以从性能角度来说,push_str通常要比+操作符更快,特别是追加大量字符串的时候。
但是+操作符的语义更清晰,代码也更简洁。在连接少量字符串时,使用+操作符可以提高代码可读性。
总结一下:
- 追加大量字符串时优先考虑
push_str,可以显著提高性能 - 连接少量字符串时,使用
+操作符可以获得更好的可读性 - 在追求性能关键的代码里,建议主要使用
push_strrather than+
所以在Rust中连接字符串时需要权衡性能和可读性,根据具体情况选择最合适的方式。
!!!








!!!
在Rust中,表示字符串的三种主要形式是:
- Bytes(字节)
- Scalar Values(标量值)
- Grapheme Clusters(字形集群)
它们之间的主要区别是:
- 字节(Bytes)
- 是字符串的最基本单位,每个字节代表一个u8的值
- 在Rust中通常用
&[u8]或Vec<u8>表示 - 对应中文中的“字节”
- 标量值(Scalar Values)
- 表示一个Unicode中的代码点(code point)
- 在Rust中通常用
char类型表示 - 对应中文中的“码点”
- 字形集群(Grapheme Clusters)
- 表示人类可读的最小单位
- 一个字形集群可能包含多个标量值组合而成
- 在Rust中通常用
&str表示 - 对应中文中的“字符”
举个例子:
字节:[229, 165, 189]
标量值:'国'
字形集群:"国"
汉字“国”包含3个字节,1个标量值,1个字形集群。
所以在Rust中正确处理字符串需要明确这三者的区别和联系。
能否举一个例子来说明如何在Rust中处理字符串的字节、标量值和字形集群?
好的,这里给一个具体的例子:
1 | fn main() { |
输出:
1 | Bytes: [72, 101, 108, 108, 111, 32, 229, 165, 189] |
这里演示了以下内容:
as_bytes()方法可以将字符串视为字节序列chars()方法可以遍历字符串的标量值graphemes()方法可以按字形集群切分字符串
另外要注意chars() 和 graphemes() 的区别:
chars()会将组合字符(如一些表情符号)拆分成多个标量值graphemes()会将它们保持为一个字形集群
这就体现了标量值和字形集群的区别。
所以在Rust中需要根据具体的处理需求来选择使用字节、标量值还是字形集群来访问字符串。
这三者分别对应Go语言的什么?举例说明
在Go语言中,字符串相关的主要类型对应Rust的字节、标量值和字形集群如下:
- 字节(Bytes)
Go中的[]byte对应Rust的字节操作。例如:
1 | s := "Hello 国" |
- 标量值(Scalar Values)
Go中的rune类型对应Rust的char。可以这样迭代:
1 | for _, r := range s { |
- 字形集群(Grapheme Clusters)
Go中直接使用string即可,因为它以UTF-8编码存储。例如:
1 | chars := []string{s[0], s[1], s[2]} // 按字形集群切分 |
另外Go中的字符串是不可变的,所以没有Rust中的push_str等方法。
总结一下对比:
| Rust | Go |
|---|---|
Vec<u8> |
[]byte |
char |
rune |
&str |
string |
所以Go语言内置了这三种字符串表示,和Rust的处理思路是一致的。
!!!






在Rust中,collect()是Iterator trait中一个很重要的方法。它的主要作用是:
将一个Iterator转换成一个集合类型(Collection)。
Iterator在Rust中是一种延迟计算(lazy)的抽象,它代表一个元素序列,但需要调用collect()等方法才会真正开始执行计算。
collect()会消费掉整个Iterator,把结果存入一个集合类型中,常见的如Vec、HashSet等。
举个例子:
1 | let v = vec![1, 2, 3]; |
这里从一个Vec创建了一个迭代器iter,然后调用collect,将迭代器的元素收集为一个新的Vec。
collect()非常强大,它可以将迭代器收集为任意的集合类型,包括Vec、HashSet、String等。
另一个例子是从Iterator收集为String:
1 | let s = [1, 2, 3] |
这里通过collect将一个数字迭代器,收集为一个字符串。
总结一下collect的主要作用:
- 消费迭代器,强制执行迭代操作
- 收集迭代器的结果为集合类型,如Vec、HashSet等
- 非常灵活,可以支持多种集合类型
它是Rust中将迭代器转换为集合的主要方式之一。
!!!













Go的ok判别式
!!!
!!!
!!!
原文链接: https://dashen.tech/2020/10/19/The-Rust-Programming-Language-配套视频-第8章-第9章/
版权声明: 转载请注明出处.