Rust 提供了强大且类型安全的字符串处理能力,核心围绕 字符串类型 和 格式化宏 展开。以下是关键知识点和操作方法的系统总结:
![图片[1]_Rust 中字符串与格式化操作方法详解_知途无界](https://zhituwujie.com/wp-content/uploads/2025/10/d2b5ca33bd20251021091855.png)
一、字符串类型:String 与 &str
1. **&str(字符串切片)**
- 本质:不可变的 UTF-8 字节序列的引用(类似字符串的“视图”)。
- 特点:
- 静态分配(如字面量
"hello"的类型是&'static str)或从String切片得到。 - 不可变(不能修改内容),常用于函数参数传递(避免所有权转移)。
- 静态分配(如字面量
- 示例:
let s: &str = "Hello, Rust"; // 字面量是 &str 类型 let string = String::from("Hello"); let slice: &str = &string[..]; // 从 String 切片得到 &str
2. **String(堆分配的可变字符串)**
- 本质:可变的、堆分配的 UTF-8 字符串(拥有所有权)。
- 特点:
- 动态增长(通过
push、push_str等方法扩展)。 - 适合需要修改内容的场景(如用户输入、动态生成的文本)。
- 动态增长(通过
- 创建方法:
let s = String::new(); // 空字符串 let s = String::from("初始值"); // 从 &str 创建 let s = "初始值".to_string(); // 等价于 String::from
3. **&str 与 String 的转换**
- **
&str→String**:通过to_string()或String::from(显式获取所有权)。let s1: &str = "hello"; let s2 = s1.to_string(); // String 类型 let s3 = String::from(s1); // 同上 - **
String→&str**:通过解引用或切片&s[..](不获取所有权)。let s = String::from("world"); let slice: &str = &s; // 自动解引用为 &str let slice2: &str = &s[..]; // 显式切片
二、字符串格式化:format!* 宏系列
Rust 通过 **format!*、write!*、println!* 等宏** 提供类型安全的格式化功能(类似 C 的 printf,但编译时检查类型匹配)。
1. **format!* 宏(生成格式化字符串)**
- 作用:返回格式化后的
String,常用于构建复杂字符串。 - 语法:
format!(格式化字符串, 参数1, 参数2, ...)。 - 占位符:
{}:按顺序填充参数(自动调用Displaytrait)。{索引}:按索引指定参数(如{0}、{1})。{字段名}:按命名字段填充(适用于结构体等)。{:格式化选项}:控制格式(如宽度、精度、对齐等)。
- 示例:
// 基础用法 let name = "Alice"; let age = 30; let s = format!("{} is {} years old.", name, age); // "Alice is 30 years old." // 指定参数顺序 let s = format!("{1} is {0} years old.", age, name); // "Alice is 30 years old." // 命名字段(需配合结构体或元组) let user = ("Bob", 25); let s = format!("{} is {} years old.", user.0, user.1); // 或使用结构体 // 格式化选项(宽度、对齐、精度) let pi = 3.1415926; let s = format!("Pi is {:.2}", pi); // 保留两位小数:"Pi is 3.14" let s = format!("{:>10}", "hi"); // 右对齐,宽度10:" hi" let s = format!("{:<10}", "hi"); // 左对齐,宽度10:"hi " let s = format!("{:^10}", "hi"); // 居中对齐,宽度10:" hi "
2. **println!* / eprintln!* / write!* 系列(输出格式化)**
- **
println!***:格式化并打印到标准输出(带换行)。 - **
eprintln!***:格式化并打印到标准错误(带换行)。 - **
write!***:格式化并写入到实现了std::io::Write的对象(如文件、缓冲区)。 - 示例:
println!("Hello, {}!", "World"); // 输出到控制台 eprintln!("Error: {}", "Something went wrong"); // 输出到 stderr use std::io::Write; let mut buffer = String::new(); write!(buffer, "Formatted: {}", 42).unwrap(); // 写入到 String 缓冲区
三、字符串常用操作方法
1. 拼接与追加
- **
+运算符**:仅限String + &str(会转移左侧String的所有权)。let s1 = String::from("Hello"); let s2 = String::from(" World"); let s3 = s1 + &s2; // s1 的所有权转移,s3 是 "Hello World" // println!("{}", s1); // 错误!s1 已失效 - **
format!***:无所有权转移(推荐多字符串拼接)。let s1 = String::from("Hello"); let s2 = String::from(" World"); let s3 = format!("{}{}", s1, s2); // s1 和 s2 仍可用 - **
push_str/push**:直接向String追加内容。let mut s = String::from("Hello"); s.push_str(" World"); // 追加 &str s.push('!'); // 追加单个 char
2. 查找与替换
- **
contains**:检查是否包含子串。let s = String::from("hello"); println!("{}", s.contains("ell")); // true - **
find/rfind**:查找子串位置(返回Option<usize>)。if let Some(pos) = s.find("ell") { println!("Found at: {}", pos); // 1 } - **
replace/replacen**:替换子串。let s = String::from("foo bar foo"); let new_s = s.replace("foo", "baz"); // "baz bar baz" let new_s = s.replacen("foo", "baz", 2); // 仅替换前 2 次
3. 分割与遍历
- **
split**:按分隔符分割为迭代器。let s = "a,b,c"; for part in s.split(',') { println!("{}", part); // 依次输出 "a", "b", "c" } - **
chars/bytes**:遍历字符或字节(注意 Unicode 支持)。for c in "你好".chars() { println!("{}", c); // 依次输出 '你', '好' }
4. 修剪空白字符
- **
trim/trim_start/trim_end**:移除首尾空白(空格、制表符、换行等)。let s = " hello "; println!("'{}'", s.trim()); // "'hello'"
四、注意事项
- UTF-8 安全:Rust 字符串默认是 UTF-8 编码,直接按字节操作(如
chars)需注意多字节字符(如中文)。 - 所有权与借用:优先使用
&str作为函数参数(避免不必要的所有权转移),需要修改时再用String。 - 格式化性能:
format!*会生成新String,高频场景可考虑write!*直接写入缓冲区。
掌握这些方法后,你可以高效安全地处理 Rust 中的字符串和格式化需求! 🦀
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容