字符串与集合类型
字符串类型
Rust 中有两种主要的字符串类型:String 和 &str。
&str:字符串切片
&str 是对字符串数据的不可变引用,通常称为“字符串切片”。
fn main() { // 字符串字面量是 &str let s: &str = "hello"; // 从 String 取切片 let string = String::from("hello world"); let slice = &string[0..5]; // &str 类型 }
String:可增长字符串
String 是堆上分配的、可增长的 UTF-8 字符串。
fn main() { // 创建 String let mut s1 = String::new(); // 空字符串 let s2 = String::from("hello"); // 从字面量创建 let s3 = "world".to_string(); // 方式二 // 追加字符串 s1.push_str("hello"); // 追加 &str s1.push('!'); // 追加单个字符 println!("{}", s1); // hello! // 拼接字符串 let s4 = s2 + " " + &s3; // 注意:s2 被移动 println!("{}", s4); // hello world // 使用 format! 宏(更灵活,不转移所有权) let s5 = format!("{} {}", s3, s1); println!("{}", s5); }
字符串索引
Rust 字符串不支持直接索引(因为 UTF-8 编码,字符长度可变):
fn main() { let s = String::from("你好"); // let c = s[0]; // 编译错误!不能直接索引 // 正确方式: for c in s.chars() { println!("{}", c); // 你, 好 } for b in s.bytes() { println!("{}", b); // 228, 189, 160, 229, 165, 189 } }
向量 Vec<T>
Vec<T> 是动态可增长的数组。
创建和修改
fn main() { // 创建方式 let mut v1: Vec<i32> = Vec::new(); let v2 = vec![1, 2, 3, 4, 5]; // 用宏创建 // 添加元素 v1.push(10); v1.push(20); v1.push(30); // 删除末尾元素 let last = v1.pop(); // Some(30) 或 None // 读取元素 let third = &v2[2]; // 直接索引,越界 panic let third = v2.get(2); // Option<&T>,安全 }
遍历
fn main() { let mut v = vec![1, 2, 3]; // 不可变遍历 for i in &v { println!("{}", i); } // 可变遍历 for i in &mut v { *i *= 2; // 解引用修改 } }
哈希表 HashMap<K, V>
创建和操作
use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert(String::from("蓝队"), 10); scores.insert(String::from("红队"), 50); // 访问 let score = scores.get("蓝队"); // Option<&i32> match score { Some(s) => println!("{}", s), None => println!("未找到"), } // 遍历 for (key, value) in &scores { println!("{}: {}", key, value); } }
entry API
use std::collections::HashMap; fn main() { let mut map = HashMap::new(); map.insert(String::from("a"), 10); // 只在键不存在时插入 map.entry(String::from("a")).or_insert(20); map.entry(String::from("b")).or_insert(30); println!("{:?}", map); // {"a": 10, "b": 30} }
本章实践:单词统计
use std::collections::HashMap; fn main() { let text = "hello world hello rust hello everyone"; let mut word_count = HashMap::new(); for word in text.split_whitespace() { let count = word_count.entry(word.to_string()).or_insert(0); *count += 1; } for (word, count) in &word_count { println!("'{}': {}", word, count); } }
本章小结
&str是字符串切片,String是可增长的堆字符串- Rust 字符串是 UTF-8 编码,不支持直接索引
Vec<T>动态数组,vec!宏方便创建HashMap<K,V>哈希表,entry API方便处理键是否存在- 集合在遍历时要注意所有权和借用规则