一、Rust 字符串概述
Rust 字符串是 UTF-8 編碼的文本序列,提供兩種主要類型:
- &str - 字符串切片(通常作為引用出現)
- String - 動態可變的、擁有所有權的字符串
二、字符串字面量 (&str)
編譯時已知大小,靜態分配在只讀內存中
let greeting: &str = "Hello, world!";
println!("字符串字面量: {}", greeting);
三、String 類型
動態分配在堆上,可增長和修改的所有權字符串
let mut s = String::from("Hello");
s.push_str(", world!");
println!("String 類型: {}", s);
四、創建 String 的多種方式
- 創建空字符串
let empty = String::new();
println!("空字符串: '{}'", empty);
- 從字面量創建
let from_literal = String::from("初始內容");
println!("從字面量創建: {}", from_literal);
- 使用 to_string() 方法
let to_string = "另一個字符串".to_string();
println!("to_string(): {}", to_string);
- 使用 format! 宏
let formatted = format!("格式化 {} {}", "字符串", 123);
println!("format! 宏: {}", formatted);
五、修改 String
let mut mutable_string = String::from("Hello");
// 添加單個字符
mutable_string.push('!');
println!("添加字符后: {}", mutable_string);// 添加字符串切片
mutable_string.push_str(" World");
println!("添加字符串后: {}", mutable_string);// 在指定位置插入
mutable_string.insert_str(6, "Rust ");
println!("插入后: {}", mutable_string);
六、字符串訪問和迭代
let text = String::from("Hello");// 獲取第一個字符(Option<char> 類型)
if let Some(first_char) = text.chars().nth(0) {println!("第一個字符: {}", first_char);
}// 迭代所有字符
print!("字符迭代: ");
for c in text.chars() {print!("{} ", c);
}
println!();// 字符串切片(注意:基于字節索引,非ASCII字符需要小心)
let slice = &text[0..1]; // "H"
println!("切片: {}", slice);
七、Unicode 和非 ASCII 字符處理
let unicode_text = "Здравствуйте"; // 俄語"你好"
println!("Unicode 文本: {}", unicode_text);// 字符數統計(不是字節數)
let char_count = unicode_text.chars().count();
let byte_count = unicode_text.len();
println!("字符數: {}, 字節數: {}", char_count, byte_count);// 遍歷 Unicode 字符
print!("Unicode 字符: ");
for c in unicode_text.chars() {print!("{} ", c);
}
println!();
八、字符串轉換和操作
let original = String::from("hello");// 轉換為大寫(返回新字符串)
let upper = original.to_uppercase();
println!("大寫: {}", upper);// 轉換為小寫
let lower = upper.to_lowercase();
println!("小寫: {}", lower);// 字符串替換
let replaced = original.replace("he", "she");
println!("替換后: {}", replaced);// 字符串分割
let sentence = "Rust is awesome!";
let words: Vec<&str> = sentence.split_whitespace().collect();
println!("分割單詞: {:?}", words);
九、&str 和 String 的關系與轉換
// &str → String(需要分配內存)
let slice: &str = "切片";
let owned: String = slice.to_string();
println!("&str 轉 String: {}", owned);// String → &str(零成本轉換)
fn process_text(text: &str) {println!("處理文本: {}", text);
}let string_data = String::from("一些數據");
process_text(&string_data); // 自動解引用轉換
十、原始字符串和轉義
// 普通轉義
let escaped = "包含\"引號\"和\\反斜杠";
println!("轉義字符串: {}", escaped);// 原始字符串(避免轉義)
let raw = r#"原始字符串: "內容" 和 \反斜杠"#;
println!("原始字符串: {}", raw);// 多級原始字符串(處理包含 # 的文本)
let complex_raw = r###"包含 # 號的 "原始" 字符串"###;
println!("復雜原始字符串: {}", complex_raw);
十一、字符串索引的注意事項
// Rust 不允許直接索引字符串(因UTF-8變長編碼)
let sample = "Rust編程";// 錯誤:不能直接索引
// let first_char = sample[0]; // 正確方式:使用字符迭代
if let Some(first) = sample.chars().nth(0) {println!("第一個字符: {}", first);
}// 獲取字符向量(注意性能開銷)
let chars: Vec<char> = sample.chars().collect();
println!("字符向量: {:?}", chars);
十二、字符串連接
// 使用 + 運算符(會獲取所有權)
let s1 = String::from("Hello");
let s2 = String::from(" World");
let combined = s1 + &s2; // s1 被移動,不能再使用
println!("連接后: {}", combined);// 使用 format! 宏(推薦,不會獲取所有權)
let s3 = String::from("Hello");
let s4 = String::from(" World");
let formatted_combine = format!("{}{}", s3, s4);
println!("format! 連接: {}", formatted_combine);
// s3 和 s4 仍然可用
十三、實用字符串方法
let example = String::from(" Rust Programming ");// 去除首尾空白
let trimmed = example.trim();
println!("去除空白: '{}'", trimmed);// 檢查是否包含子串
let contains = example.contains("Rust");
println!("包含 'Rust': {}", contains);// 查找子串位置
if let Some(pos) = example.find("Programming") {println!("'Programming' 位置: {}", pos);
}// 字符串長度(字節數)
println!("字節長度: {}", example.len());// 判斷是否為空
println!("是否為空: {}", example.is_empty());
十四、總結:
- &str: 靜態、不可變、零成本抽象的字符串視圖
- String: 動態、可變、擁有所有權的字符串
- UTF-8 編碼確保完整的 Unicode 支持
- 設計注重內存安全和性能
- 豐富的API支持各種字符串操作
性能提示:頻繁的字符串修改建議使用 String,只讀操作使用 &str