String

17 Mar 2025 | 5 分钟阅读

Rust 包含两种类型的字符串:&strString

String

  • 字符串被编码为 UTF-8 序列。
  • 字符串在堆内存中分配。
  • 字符串的大小是可增长的。
  • 它不是以 null 结尾的序列。

&str

  • '&str' 也称为字符串切片。
  • 它由 &[u8] 表示,用于指向 UTP-8 序列。
  • '&str' 用于查看字符串中存在的数据。
  • 它的大小是固定的,即它无法调整大小。

'String' 和 '&str' 之间的区别。

  • String 是一个可变引用,而 &str 是对字符串的不可变引用,即我们可以更改 String 的数据,但无法操作 &str 的数据。
  • String 拥有其数据的所有权,而 &str 没有所有权,它从另一个变量借用。

创建一个新的 String

String 的创建方式与我们创建向量的方式类似。让我们看看

创建一个空的 String

在上面的声明中,String s 是通过使用 new() 函数创建的。现在,如果我们在声明时初始化 String,我们可以通过使用 to_string() 方法来实现这一点。

  • 在数据上实现 to_string() 方法
  • 我们也可以直接在字符串字面值上实现 to_string 方法

让我们通过一个例子来理解这一点

输出

javaTpoint tutorial
  • 创建 String 的第二种方法是使用 String::from 函数,这等同于 String::new() 函数。

让我们通过一个简单的例子来理解这一点

输出

javaTpoint tutorial

更新一个 String

我们还可以通过将更多数据推送到 String 中来更改 String 的大小和内容。我们还可以使用 format! 宏的 '+' 运算符来连接字符串值。

Rust String
  • 使用 push_str 和 push 追加到字符串

push_str() : 我们可以使用 push_str() 函数来增大 String 的大小。它将内容追加到字符串的末尾。假设 s1 和 s2 是两个字符串,我们想将字符串 s2 追加到字符串 s1。

让我们通过一个简单的例子来理解这一点

输出

java is a programming language

push_str() 函数不获取参数的所有权。让我们通过一个简单的例子来理解这种情况。

输出

World

如果 push_str() 函数获取参数的所有权,那么程序的最后一行将不起作用,并且不会打印 s2 的值。

push() : push() 函数用于在字符串末尾添加单个字符。假设字符串是 s1,字符 ch 将添加到字符串 s1 的末尾。

让我们看一个简单的例子

输出

javac
  • 使用 '+' 运算符或 format 宏进行连接

'+' 运算符: '+' 运算符用于连接两个字符串。让我们看看

让我们看一个简单的例子

输出

javaTpoint tutorial!!

在上面的示例中,s3 包含两个字符串连接的结果,即 javaTpoint 教程。's1' 不再有效,并且我们使用 s2 的引用,即 &s2,这符合当我们使用 '+' 运算符时调用的方法的签名。'+' 运算符调用 add() 方法,其声明如下

首先,s2 有一个 '&' 运算符,这意味着我们正在向 s1 添加一个引用。根据 add() 函数的签名,我们可以向 String 添加 &str,并且我们不能将两个字符串值加在一起。但是,根据 add() 方法中指定的第二个参数,s2 的类型是 &String 而不是 &str。但是,我们仍然能够在 add 方法中使用 s2,因为编译器将 &string 强制转换为 &str。因此,我们可以说,当我们调用 add() 方法时,Rust 使用了 deref 强制转换

其次,add() 函数的第一个参数是 self,并且 add() 拥有 self 的所有权。这意味着在语句 let s3=s1+&s2; 之后,s1 不再有效。

  • format! 宏
    • 当我们想连接多个字符串时,在这种情况下使用 '+' 运算符会变得非常笨拙。要连接多个字符串,最好使用 format 宏。
    • format 宏的工作方式与 println! 宏类似。format 宏和 println! 宏的区别在于 format 宏不会在屏幕上打印,它返回字符串的内容。

让我们通过一个简单的例子来理解这一点

输出

      C is a programming language.

字符串的索引

String 以 UTF-8 序列编码。因此,字符串不能被索引。让我们通过一个例子来理解这个概念

输出

error[E0277]: the trait bound `std::string::String: std::ops::Index<{integer}>` is not satisfied
 --> jdoodle.rs:4:17
  |
4 |     print!("{}",s[1]);
  |                 ^^^^ the type `std::string::String` cannot be indexed by `{integer}`
  |
  = help: the trait `std::ops::Index<{integer}>` is not implemented for `std::string::String`

error: aborting due to previous error

通过索引访问速度非常快。但是,字符串是以 UTF-8 序列编码的,它可以有多个字节,并且找到字符串中的第 n 个字符将证明是一个昂贵的操作。

字符串切片

字符串中未提供索引,因为它不知道索引操作的返回类型应该具有字节值、字符或字符串切片。Rust 提供了一种更具体的方式来索引字符串,方法是在 [] 内提供一个范围,而不是一个数字。

让我们来看看

在上述情况下,s 包含字符串字面值,即 Hello World。我们指定 [1..4] 索引,这意味着我们正在从字符串 s 索引 1 到 3 中提取子字符串。

输出

ell

迭代字符串的方法

我们也可以通过其他方式访问字符串。我们可以使用 chars() 方法来迭代字符串的每个元素。

让我们看一个简单的例子

输出

C is a programming language

下一节教程