当前位置: 首页 > news >正文

rust for循环里的所有权 - into_iter / iter / iter_mut

文章目录

  • 1 遍历对象实质为 .into_iter() 生成的迭代器
  • 2 避免转移 .iter() / .iter_mut()
  • 3 for循环里自变量为什么不用加mut

// for循环语法糖
for loop_variable in iterator {code()
}
// 解糖
{let result = match IntoIterator::into_iter(iterator) {mut iter => loop {match iter.next() {None => break,Some(loop_variable) => { code(); },};},};result
}

1 遍历对象实质为 .into_iter() 生成的迭代器

fn into_iter(self) -> Self::IntoIter
(注意:这里的IntoIter是关联类型,自定义的类型别名)
遍历未实现Copy trait的对象将发生所有权转移

let a = vec![0, 1]; // Vec未实现Copy trait
for i in a {i;}
// a; // 去掉注释;报错,a所有权转移

2 避免转移 .iter() / .iter_mut()

fn iter(&self) -> Iter
fn iter_mut(&mut self) -> IterMut
1)

let a = vec![0, 1]; 
for i in a.iter() {i;}
a; 

实际上,for循环可以遍历所有实现IntoIterator trait的对象,而IntoIterator trait必须实现的方法就是into_iter();
Iter和IterMut也都实现了IntoIterator trait,所以可以理解为上述代码解糖后操作的对象是a.iter().into_iter(),而基本库里Iter对象into_iter()方法实现是这样的:

impl<I: Iterator> IntoIterator for I {type Item = I::Item;type IntoIter = I; // 类型IntoIter就是待实现对象的类型,这里也就是Iter#[inline]fn into_iter(self) -> I {self // 将iter()产生的Iter对象原封不动地返回,但之前对象的所有权已经转移}
}

.into_iter()a.iter()原封不动地返回,此时for循环遍历的对象实质就是a.iter(),而.iter()传递的是调用者的引用

2)
另一种写法就是直接遍历对象的引用

    let a = vec![0, 1]; for i in &a {i;}a; 

不可变引用都实现了 Copy trait这里自然不存在所有权转移;
同时,【摘自文档 https://rustwiki.org/zh-CN/std/iter/index.html】如果集合类型 C 提供 iter(),则它通常还为 &C 实现 IntoIterator,而该实现只是调用 iter()。 同样,提供 iter_mut() 的集合 C 通常通过委派给 iter_mut() 来为 &mut C 实现 IntoIterator。
所以,这里实际上操作的对象还是a.iter()
p.s 方法的调用会自动解引用,故&a.iter()和a.iter()等价

3 for循环里自变量为什么不用加mut

从文章开头贴出的代码可以看到,解糖后的代码自变量loop_variable实际只是存在于单次循环中的一个临时变量,可以理解成每次循环都会完成一次let loop_variable = iter.next();的赋值操作, 所以,自变量无需mut也能发生变化;当然,添加了mut也不会报错,只是会多个警告提示。

http://www.lryc.cn/news/288069.html

相关文章:

  • GitHub README-Template.md - README.md 模板
  • 【文本到上下文 #6】Word2Vec、GloVe 和 FastText
  • yolov5 opencv dnn部署自己的模型
  • Cortex-M4处理器 电源管理
  • Linux 驱动开发基础知识——编写LED驱动程序(三)
  • YOLOv8 视频识别
  • elementplus Dialog 对话框设置距离页面顶部的距离
  • 便捷接口调测:API 开发工具大比拼 | 开源专题 No.62
  • openssl3.2/test/certs - 008 - root-nonca trust variants: +serverAuth +anyEKU
  • cg插画设计行业怎么样,如何学习插画设计
  • 1.25学习总结
  • C语言每日一题(48)回文链表
  • 提高代码效率的5个Python内存优化技巧
  • 基于一款热门大屏可视化设计器使用教程
  • 梯度下降法、模拟训练、拟合二次曲线、最小二乘法、MSELoss、拟合:f(x)=ax^2+bx+c
  • Web3.0投票如何做到公平公正且不泄露个人隐私
  • 灰度图像的自动阈值分割
  • 利用Maven获取jar包
  • 将vue组件发布成npm包
  • 江科大STM32 中
  • vue+draggable+el-upload上传图片拖拽重排方法
  • 微信的新版canvas绘制的图案发生变形和偏移的问题
  • [ACM学习] 进制转换
  • redis + 拦截器 :防止数据重复提交
  • 如何进行H.265视频播放器EasyPlayer.js的中性化设置?
  • Ubuntu22.04安装4090显卡驱动
  • YOLOv8优化策略:注意力涨点系列篇 | 一种轻量级的加强通道信息和空间信息提取能力的MLCA注意力
  • 【新书推荐】2.5节 有符号整数和无符号整数
  • RT-Thread: 串口操作、增加串口、串口函数
  • 自然语言处理的新突破:如何推动语音助手和机器翻译的进步