Rust中遍历时常用的引用类型

举报
yd_289945139 发表于 2026/10/23 11:59:16 2026/10/23
【摘要】 Rust中遍历时常用的引用类型 1. 不可变引用(&T)- 最常用 大多数场景使用不可变引用:let vec = vec![1, 2, 3, 4, 5];// for循环默认使用不可变引用for item in &vec { // 等价于 for item in vec.iter() println!("{}", item); // item是 &i32 类型}// 直接遍历集合...

Rust中遍历时常用的引用类型

1. 不可变引用(&T)- 最常用

大多数场景使用不可变引用:

let vec = vec![1, 2, 3, 4, 5];

// for循环默认使用不可变引用
for item in &vec {  // 等价于 for item in vec.iter()
    println!("{}", item);  // item是 &i32 类型
}

// 直接遍历集合本身会消耗所有权
// for item in vec {  // vec的所有权被移动!
//     println!("{}", item);
// }

// 推荐:使用 .iter() 获取不可变引用
for item in vec.iter() {
    println!("{}", item);
}

2. 可变引用(&mut T)- 需要修改时使用

需要修改集合元素时使用:

let mut vec = vec![1, 2, 3, 4, 5];

// 使用可变引用遍历并修改
for item in &mut vec {  // 等价于 for item in vec.iter_mut()
    *item *= 2;  // 修改每个元素
}

println!("{:?}", vec);  // [2, 4, 6, 8, 10]

区分三种迭代方式:

let vec = vec![1, 2, 3];

// 1. 不可变引用遍历(不消耗所有权)
for item in vec.iter() {  // item: &i32
    println!("{}", item);
}
println!("vec还能用: {:?}", vec);  // vec仍然有效

// 2. 可变引用遍历(不消耗所有权)
let mut vec2 = vec![1, 2, 3];
for item in vec2.iter_mut() {  // item: &mut i32
    *item *= 2;
}
println!("修改后: {:?}", vec2);

// 3. 消耗所有权遍历(vec会被移动)
let vec3 = vec![1, 2, 3];
for item in vec3.into_iter() {  // item: i32
    println!("{}", item);
}
// println!("{:?}", vec3);  // 错误!vec3已被消耗

3. 常见的遍历场景

遍历向量:

let nums = vec![1, 2, 3, 4, 5];

// 方式1:使用引用(推荐)
for num in &nums {
    println!("{}", num);
}

// 方式2:使用索引
for i in 0..nums.len() {
    println!("{}", nums[i]);
}

// 方式3:使用 enumerate 获取索引
for (i, num) in nums.iter().enumerate() {
    println!("索引{}的值是{}", i, num);
}

遍历哈希表:

use std::collections::HashMap;

let mut scores = HashMap::new();
scores.insert("Alice", 10);
scores.insert("Bob", 20);

// 遍历键值对(使用不可变引用)
for (name, score) in &scores {
    println!("{}: {}", name, score);
}

// 遍历并修改值
for score in scores.values_mut() {
    *score += 5;
}

遍历数组:

let array = [1, 2, 3, 4, 5];

// 数组实现了 Copy,所以遍历方式更多样
for item in array {  // 数组本身会被复制
    println!("{}", item);
}

for item in &array {  // 使用引用,避免复制
    println!("{}", item);
}

4. 智能指针的遍历

遍历包含智能指针的集合:

use std::rc::Rc;

let items = vec![
    Rc::new("hello".to_string()),
    Rc::new("world".to_string()),
];

// 遍历Rc的引用
for item in &items {
    println!("{}", item);  // item是 &Rc<String>
}

// 获取内部值的引用
for item in items.iter() {
    let s: &String = item.as_ref();
    println!("{}", s);
}

5. 遍历中的借用规则

let mut vec = vec![1, 2, 3, 4, 5];

// 正确:在循环中使用不可变引用
for item in &vec {
    println!("{}", item);
    // vec.push(6);  // 错误!不能同时存在可变和不可变借用
}

// 正确:循环结束后再修改
for item in &vec {
    println!("{}", item);
}
vec.push(6);  // 循环结束后,借用已释放,可以修改

// 可变引用遍历时注意
for item in &mut vec {
    *item += 1;
    // println!("{:?}", vec);  // 错误!可变借用存在时不能使用vec
}
println!("{:?}", vec);  // 循环结束后可以访问

总结表

遍历场景 推荐的引用类型 方法 备注
只读遍历 不可变引用 &T .iter() 或 &collection 最常用
修改元素 可变引用 &mut T .iter_mut() 或 &mut collection 需要修改内容时使用
消耗所有权 值本身 T .into_iter() 集合不再需要时使用
数组遍历 不可变引用 &T &array 数组实现Copy,但用引用更好
智能指针 不可变引用 &Rc<T> .iter() 通过 .as_ref() 获取内部值引用

最佳实践建议

  1. 默认使用不可变引用:for item in &collection 或 collection.iter()
  2. 需要修改时用可变引用:for item in &mut collection 或 collection.iter_mut()
  3. 避免所有权转移:除非明确需要消耗集合,否则不要用 .into_iter()
  4. 注意借用检查:遍历期间不能同时有其他借用

简单记忆口诀

- 只读不写用 &      (不可变引用)
- 需要修改用 &mut   (可变引用)  
- 不再需要用 into   (消耗所有权)
- 默认就用 .iter()  (最安全)
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。