1、String:堆分配的字符串
let mut s = String::from("Hello");
s.push_str(", world!"); // 可变修改2、&str:字符串切片的不可变借用
fn print_text(s: &str) {
println!("{}", s);
}3、&String:String的不可变借用(核心新增内容)
let my_string = String::from("Rust");
let my_str: &str = &my_string; // 自动类型转换特性 | &str | &String |
内存布局 | 指针+长度 | 指向String的指针 |
适用场景 | 函数参数/视图 | 临时引用String对象 |
大小 | 2个usize | 1个usize |
生命周期 | 可独立 | 与源String绑定 |
4、字符串字面值:&'static str
let literal: &'static str = "Rust";1、类型转换规则
Rust编译器自动执行以下转换:

函数应统一使用&str参数:
fn process(text: &str) { /*...*/ }
let s = String::from("hello");
let literal = "world";
process(&s); // &String → &str
process(literal); // &str直接使用2、性能差异
// 不推荐:双重指针访问
fn slow_example(s: &String) {
let first_char = s.chars().next();
}
// 推荐:直接访问字符串数据
fn fast_example(s: &str) {
let first_char = s.chars().next();
}3、使用场景
a、函数参数传递
b、只读数据访问
// 获取String容量信息
fn get_capacity(s: &String) -> usize {
s.capacity()
}1、UTF-8编码强制规范
Rust强制字符串为UTF-8编码:
let emoji = ""; // 有效UTF-8
// let invalid = String::from_utf8(vec![0xFF]); // 编译报错2、内存安全三重保障
3、引用类型优化
编译器优化&String访问:
let len = (&my_string).len(); // 实际生成my_string.len()的机器码4、索引陷阱与解决方案
避免切分无效UTF-8序列:
let s = "Здравствуйте"; // 俄语
// let slice = &s[0..1]; // Panic: 字节位置无效
let safe_slice = &s[0..4]; // 正确:З 占2字节安全替代方案:
// 按字符遍历
for c in "नमस्ते".chars() {
println!("{}", c);
}
// 按字节操作
let bytes = "Rust".as_bytes();操作 | String | &str | &String |
创建 | String::from("Rust") | "直接使用" | &my_string |
转换 | s.as_str() → &str | s.to_string() | (*s).clone()→String |
拼接 | s1 + &s2 | format!("{}{}") | 不适用 |
切片 | s[0..4] → &str | &s[2..5] | &s[0..2] → &str |
获取元数据 | s.capacity() | s.len() | s.capacity() |
最佳实践:
1、OsString处理平台字符串:
use std::ffi::OsString;
let os_str = OsString::from("文件.txt"); // Windows自动转UTF-162、CString跨语言交互:
use std::ffi::CString;
let c_str = CString::new("Rust").unwrap(); // 自动添加NULL终止符
unsafe { libc_print(c_str.as_ptr()); }3、FFI字符串处理黄金规则:
1、预分配内存减少堆分配:
let mut s = String::with_capacity(1024); // 预留1KB空间2、内存复用避免重复分配:
s.clear(); // 清空内容保留内存
s.push_str("New"); // 重用已分配内存3、拼接优化:
// 差:创建多个临时String
let s = s1 + &s2 + &s3;
// 优:单次分配
let mut s = String::new();
s.push_str(s1);
s.push_str(s2);4、避免&String传递减少指针跳转
Rust的字符串设计体现了其核心原则:
//掌握三种字符串类型的转换边界,就是掌握Rust字符串的心法:
&String → &str → String
↑___________| |
|______________________↓黄金法则: