Updated src/common_collections/string.md'.

This commit is contained in:
Hector PENG
2026-03-16 18:45:31 +08:00
parent 3d5fec579f
commit e91e50dcbf
3 changed files with 35 additions and 40 deletions

View File

@@ -1,8 +1,6 @@
[package]
name = "string_demo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
edition = "2024"
[dependencies]

View File

@@ -1,11 +1,10 @@
fn main() {
let s = "नमस्ते";
let data = "初始内容";
for c in s.chars() {
println! ("{}", c);
}
let s = data.to_string();
for b in s.bytes() {
println! ("{}", b);
}
// 该方法直接在字面值之上也工作
let s = "初始内容".to_string();
println! ("{s}");
}

View File

@@ -1,69 +1,69 @@
# 以字符串存储 UTF-8 编码的文本
在第 4 章中,我们曾讨论过字符串,现在我们将对其进行更深入研究。新 Rust 公民通常卡在字符串上,原因有三
我们在第 4 章中讨论过字符串,现在我们将更深入研究他们。新 Rustacean 们通常会因为以下三个原因的结合,而在字符串上陷入困境
- Rust 暴露可能错误的倾向;
- 字符串种比许多程序员认为的更复杂的数据结构;
- Rust 暴露可能错误的倾向;
- 字符串属于一种比许多程序员认为的更复杂的数据结构;
- 以及 UTF-8。
当咱们从其他编程语言转至 Rust 时,这些因素就会以看起来很难的方式,纠缠在一起。
当咱们从其他编程语言时,这些因素以一种看似困难的方式结合在一起。
我们之所以会在集合语境下讨论字符串,是因为字符串是作为字节集合,加上一些在这些字节被解释为文本时提供有用功能的方法实现的。在本节中,我们将讨论那些 `String` 上的、每种集合类型都有的操作,比如创建、更新及读取等。我们还将讨论 `String` 与其他集合的不同之处,即由于人与计算机在解析 `String` 数据的差异,而对 `String` 的索引会变得如何复杂。
我们之所以会在集合的上下文中讨论字符串,是因为字符串是作为字节集合实现的,加上一些在这些字节被解释为文本时提供有用功能的方法。在这一小节中,我们将讨论 `String` 上的、每种集合类型都有的操作,比如创建、更新及读取等。我们还将讨论 `String` 与其他集合的不同之处,即由于人与计算机在解析 `String` 数据方式上的差异,而怎样导致`String` 的索引会变得复杂。
## 何为字符串
## 定义字符串
我们将首先定义 *字符串* 这一术语的含义。Rust 在核心语言中只有一种字符串类型,即通常以其借用形式 `&str` 看到的字符串切片 `str`。在第 4 章中,我们讨论过 [字符串切片](../ownership/the_slice_type.md#字符串切片),他们属于对存储在别处的一些 UTF-8 编码字符串数据的引用。例如,字符串的字面值存储在程序的二进制文件中,而因此属于字符串切片。
所谓 `String` 类型,是由 Rust 的标准库提供而非编码到核心语言中是一种可增长、可变、被拥有所有权、UTF-8 编码的字符串类型。当 Rustacean 们提及 Rust 中的 “字符串” 时,他们可能指的要么是 `String`,或者是字符串切片 `&str` 类型,而不单是这两种类型之一。虽然这一小节主要是有关 `String`,但这两种类型在 Rust 的标准库中都大量使用,并且 `String` 和字符串切片都是 UTF-8 编码的。
我们将首先定义出所谓 *字符串* 的含义。Rust 的核心语言中,只有一种字符串类型,即通常以其借用形式 `&str` 出现的字符串切片 `str`。在第 4 章我们曾谈到过 [*字符串片切片*](../ownership/the_slice_type.md#字符串切片),他们是对存储在别处的 UTF-8 编码字符串数据的一些引用。例如,字符串的字面值,就存储在程序的二进制文件中,而因此属于一些字符串的切片。
所谓 `String` 类型,则是由 Rust 的标准库提供而未被编码到核心语言是种可增长、可变、有所有权、UTF-8 编码的字符串类型。当 Rust 公民提及 Rust 中的 “字符串” 时,他们可能指的是 `String` 或字符串切片的 `&str` 类型,而不单是其中一种类型。虽然本节主要讨论 `String`,但这两种类型在 Rust 的标准库中都有大量使用,同时 `String` 和字符串切片均为 UTF-8 编码的。
## 创建一个新的 `String`
`Vec<T>` 的许多相同操作对 `String` 也可使用,因为 `String` 实际上是作为字节矢量的封装器实现的,不过带有一些额外的保证、限制及功能。`Vec<T>``String` 下以同一方式工作的函数示例,便是创建出一个实例的 `new` 函数,如下清单 8-11 所示。
## 创建新的 `String`
由于 `String` 实际上是作为对字节矢量的封装器实现的,并有着一些额外的保证、限制及功能,因此可用于 `Vec<T>` 的许多相同操作也可用于 `String`。一个在 `Vec<T>``String` 上工作方式相同的函数示例,便是创建实例的 `new` 函数,如下清单 8-11 中所示。
<a name="listing_8-11"></a>
```rust
let mut s = String::new();
```
*清单 8-11创建一个新的空 `String`*
**清单 8-11**:创建一个新的空 `String`
这行代码创建出一个名为 `s` 的新空字符串,后我们可以向其中加载数据。通常情况下,我们会使用一些咱们开始字符串的初始数据。为此,我们会使用 `to_string` 方法,该方法适用于任何实现了 `Display` 特质的类型,正如字符串字面量那样。下面清单 8-12 展示了两个示例。
这行代码创建个名为 `s` 的新空字符串,后我们可以加载数据到其中。通常,我们将有一些我们打算以其开始字符串的初始数据。为此,我们会使用 `to_string` 方法,其在任何实现了 `Display` 特质的类型上都可用,字符串字面量便如此。下面清单 8-12 展示了两个示例。
<a name="listing_8-12"></a>
```rust
let data = "初始内容";
let s = data.to_string();
// 该方法同样直接工作于字面值之上
// 该方法直接在字面值之上也工作
let s = "初始内容".to_string();
```
*清单 8-12使用 `to_string` 方法从某个字符串字面值创建 `String`*
**清单 8-12**:使用 `to_string` 方法从字符串字面值创建 `String`
这段代码会创建一个包含 `初始内容` 的字符串。
我们还可以使用函数 `String::from`,从某个字符串字面量创建出字符串。下面清单 8-13 中的代码,等同于清单 8-12 中使用 `to_string` 的代码。
这段代码会创建一个包含 `初始内容` 的字符串。
我们还可使用函数 `String::from` 从字符串字面量创建 `String`。下面清单 8-13 中的代码与清单 8-12 中使用 `to_string` 的代码等价。
<a name="listing_8-13"></a>
```rust
let s = String::from("初始内容");
```
*清单 8-13使用 `String::from` 函数,从某个字符串字面值创建 `String`*
**清单 8-13**:使用 `String::from` 函数字符串字面值创建 `String`
由于字符串的用途非常广泛,我们可以使用许多不同的字符串通用 API从而为我们提供了大量选择。其中有些看起来是多余,但他们都有自己的用武之地!在这个示例中`String::from``to_string` 做的是同一件事,所以咱们选择哪个只是风格与可读性的问题
由于字符串的用途非常广泛,我们可以使用许多不同的字符串通用 API从而提供给我们很多选择。其中一些 API 看似多余,但他们都有他们的用处!在这一情形下`String::from``to_string` 完成同一件事,因此咱们选择哪个取决于样式与可读性。
请记住,字符串是 UTF-8 编码,因此我们可以在中包含任何正确编码的数据,如下清单 8-14 所示。
请记住,字符串是 UTF-8 编码,因此我们可以在他们中包含任何正确编码的数据,如下清单 8-14 所示。
<a name="listing_8-14"></a>
```rust
let hello = String::from("السلام عليكم");
let hello = String::from("Dobrý den");
@@ -79,16 +79,14 @@
let hello = String::from("👋");
```
*清单 8-14以字符串存储不同语言的问候语*
**清单 8-14**:以字符串存储不同语言的问候语
所有这些都是有效的 `String` 值。
## 更新字符串
咱们向某个 `String`压入更多数据时,其大小和内容都会发生变化,就像 `Vec<T>` 的内容一样。此外,咱们可以方便地使用 `+` 运算符或 `format!`连接多个 `String` 值。
咱们压入更多数据到 `String`时,其大小会增加且其内容会变化,就像 `Vec<T>` 的内容一样。此外,咱们可以方便地使用 `+` 运算符或 `format!` 宏连接 `String` 值。
### 使用 `push_str` 与 `push` 追加内容到某个 `String`