Rust中&str与&String辨析

本篇将介绍Rust中字符串,&str与&String辨析和其最佳实践。
字符串
当 Rust 用户提到字符串时,往往指的就是 String
类型和&str
字符串切片类型,这两个类型都是 UTF-8 编码。二者生成方式各有不同。
- String
1
String::from("hello,world");
- &str
实际上字符串字面量既是&str,即使切片1
let s: &str = "Hello, world!";
二者之间如何转化呢。
- &str 类型生成 String 类型
1
2
3String::from("hello,world")
"hello,world".to_string()
"hello,world".to_owned() - String 类型转为 &str
这个也很简单,取引用及可。之所以这样可行,是因为deref 隐式强制转换
(Rust 有一个机制叫做Deref coercion
(自动解引用转换),允许你将&String 自动转换成 &str
,因为 String 实现了 Deref<Target = str>。)1
2
3
4
5
6
7
8
9
10fn main() {
let s = String::from("hello,world!");
say_hello(&s);
say_hello(&s[..]);
say_hello(s.as_str());
}
fn say_hello(s: &str) {
println!("{}",s);
}
操作字符串
这里API所操作的字符串,类型都是String,因为String是可变字符串,这里简单介绍几个
push
在字符串尾部可以使用 push()
方法追加字符 char
,也可以使用 push_str()
方法追加字符串字面量
。这两个方法都是在原有的字符串上追加,并不会返回新的字符串。由于字符串追加操作要修改原来的字符串,则该字符串必须是可变的,即字符串变量必须由 mut 关键字修饰。
1 | fn main() { |
insert
可以使用 insert()
方法插入单个字符 char
,也可以使用 insert_str()
方法插入字符串字面量
,与 push() 方法不同,这俩方法需要传入两个参数,第一个参数是字符(串)插入位置的索引,第二个参数是要插入的字符(串),索引从 0 开始计数,如果越界则会发生错误。由于字符串插入操作要修改原来的字符串,则该字符串必须是可变的,即字符串变量必须由 mut 关键字修饰。
1 | fn main() { |
此外还有替换 (Replace),删除 (Delete,与字符串删除相关的方法有 4 个,它们分别是 pop(),remove(),truncate(),clear()。这四个方法仅适用于 String 类型
。),连接 (Concatenate)
最佳实践
尽管有这么多API来操作字符串,尤其是日常开发中,我们经常可以在可变的String上使用push和push_str方法来建立字符串,或者使用其+操作符。 然而,使用format!
往往更方便,特别是在有字面和非字面字符串
混合的地方。
1 |
|
到底该怎么使用&str和&String
事实上,你应该总是倾向于使用借用类型
而不是借用所有类型
。 例如&str而不是&String,&[T]而不是&Vec
我们希望确定一个词是否包含三个连续的元音。我们不需要拥有字符串来确定这一点,所以我们将使用一个引用。
1 | fn three_vowels(word: &String) -> bool { |
如果我们在最后两行取消注释,这个例子就会失败,因为&str类型不会被强制变成&String类型。
例如,如果我们把我们的函数声明改成:
1 | fn three_vowels(word: &str) -> bool {} |
那么这两个版本都会编译并打印相同的输出。
1 | Ferris: false |
关键在于就是,&String 自动解引用为 &str。所以我们总是采取借用类型作为函数的参数。
- Title: Rust中&str与&String辨析
- Author: tianyi
- Created at : 2025-08-05 10:33:18
- Updated at : 2025-08-05 11:31:36
- Link: https://github.com/ztygod/2025/08/05/Rust中-str与-String辨析/
- License: This work is licensed under CC BY-NC-SA 4.0.