Rust的Reborrow机制
最近,在使用Rust时遇到了Reborrow的概念,记录下来以备以后参考。
1. 起因
起因准备对数据进行Min-Max标准化处理,也就是将一系列数据映射到一个新的范围。
首先,需要遍历数据,找出其中的最大值和最小值,然后通过公式改变原始数据集的值。
Min-Max公式:标准化后的值 = (原始值 - 最小值) / (最大值 - 最小值)
简化后的代码如下:
fn main() {
let mut values = vec![10.5, 22.3, 103.5, 45.75];
let v = &mut values;
println!("原始数据: {:#?}", v);
let mut max = f64::MIN;
let mut min = f64::MAX;
for n in v {
if *n > max {
max = *n;
}
if *n < min {
min = *n;
}
}
println!("max is {}", max);
println!("min is {}", min);
println!("开始Min-Max标准化处理...");
for n in v {
*n = (*n - min) / (max - min);
}
println!("处理后数据: {:#?}", values);
}
运行时有如下错误:
error[E0382]: use of moved value: `v`
--> src/main.rs:22:14
|
3 | let v = &mut values;
| - move occurs because `v` has type `&mut Vec<f64>`, which does not implement the `Copy` trai
t
...
9 | for n in v {
| - `v` moved due to this implicit call to `.into_iter()`
...
22 | for n in v {
| ^ value used here after move
|
大概是第9行遍历v的找出最大值和最小值时候,可变借用v的使用权已经转移了,
所以在第22行想再次遍历v去修改值的时候,出现错误。
这里,因为Vector没有实现Copy Trait,所以它的可变借用在第一次遍历时,由于隐式的调用了.into_iter(),所有权发生了转移。
如果想多次遍历Vector,可以使用它的不可变借用,比如定义let v = &values;
那么,就可以多次遍历v,因为不可变借用都实现了Copy Trait。
但是,我第二次遍历v的时候,还需要修改其中的值,所以必须定义为可变借用let v = &mut values;
通过查询资料,发现Reborrow的机制可以实现上面的需求。
2. Reborrow概念
借用(Borrow)是Rust中的一个重要概念,它是允许代码访问某个值而不获取其所有权的一种机制。
而Reborrow则是指在一个已存在的借用基础上创建一个新的借用,
这个新的借用可以是不可变的,也可以是可变的(前提是原始借用是可变的,并且没有其他借用存在)。
总的来说,Reborrow通过在已存在的借用上创建新的借用,从而扩展引用的生命周期并在更广泛的作用域内安全地访问值。
3. 解决方法
下面通过实践来检验对Reborrow概念的理解。
回到第一节中遇到的问题,解决方式就是在第一次遍历v时(第9行),不要把所有权转移出去,
这样,第二次遍历v(第22行)的时候,就不会报出"value used here after move"的错误。
根据Reborrow的机制,我们在第9行可以Reborrow可变借用v,这样转移出去的是被再次借用的v,而不是v本身。
改变方法很简单,第9行改为for n in &*v {即可,也就是先还原v(*v),然后Reborrow(&*v)。
修改后再次运行代码:
$ cargo run
原始数据: [
10.5,
22.3,
103.5,
45.75,
]
max is 103.5
min is 10.5
开始Min-Max标准化处理...
处理后数据: [
0.0,
0.12688172043010754,
1.0,
0.3790322580645161,
]
values中的数据可以正常转换了。
注意,这里是将vReborrow成一个不可变借用&*v,因为我第一次遍历时不需要改变v。
如果想vReborrow成一个可变借用,可以写成:&mut *v。
Rust的Reborrow机制的更多相关文章
- Rust语言:安全地并发
http://www.csdn.net/article/2014-02-26/2818556-Rust http://www.zhihu.com/question/20032903 Rust是近两年M ...
- 半个月使用rust语言的体验
从第一次下载rust语言的编译器到今天刚好第14天. 简单说一下对这个语言的感觉吧. 一.性能 把以前用java写的一个中文地址切分的算法,用rust重新实现了一下(https://github.co ...
- Rust到底值不值得学--Rust对比、特色和理念
前言 其实我一直弄不明白一点,那就是计算机技术的发展,是让这个世界变得简单了,还是变得更复杂了. 当然这只是一个玩笑,可别把这个问题当真. 然而对于IT从业者来说,这可不是一个玩笑.几乎每一次的技术发 ...
- Rust入坑指南:万物初始
有没有同学记得我们一起挖了多少个坑?嗯-其实我自己也不记得了,今天我们再来挖一个特殊的坑,这个坑可以说是挖到根源了--元编程. 元编程是编程领域的一个重要概念,它允许程序将代码作为数据,在运行时对代码 ...
- the rust book 的简单入门笔记
rust learning day 1 (2021/05/27) 学了常量,变量,数据类型,控制流,所有权 char 的宽度是4字节,一个 unicode 的宽度 控制流条件都不要括号 rust 中的 ...
- Rust所有权及引用
Rust 所有权和借用 Rust之所以可以成为万众瞩目的语言, 就是因为其内存安全性. 在以往内存安全几乎全都是通过GC的方式实现, 但是GC会引来性能.CPU以及Stop The World等问题, ...
- 最强肉坦:RUST多线程
Rust最近非常火,作为coder要早学早享受.本篇作为该博客第一篇学习Rust语言的文章,将通过一个在其他语言都比较常见的例子作为线索,引出Rust的一些重要理念或者说特性.这些特性都是令人心驰神往 ...
- Rust实战系列-基本语法
本文是<Rust in action>学习总结系列的第二部分,更多内容请看已发布文章: 一.Rust实战系列-Rust介绍 " 主要介绍 Rust 的语法.基本类型和数据结构,通 ...
- 学习Rust第一天 Rust语言特点
学习Rust之前,我觉得应该首先了解Rust语言的设计目的是什么?为什么会诞生这门语言?这门语言和其他的语言有什么不同. Rust语言的设计特点 高性能:rust拥有和C++相近的性能表现,所以在嵌入 ...
- Rust借用机制的理解分析
Rust初学者大多会遇到这样的问题: 为什么同一资源不可被同时可变借用和不可变借用? 为什么Rc一定只能是只读的,一定要配合std::cell系列(Cell,RefCell,UnsafeCell)才能 ...
随机推荐
- 基于surging的产品项目-木舟开源了!
一 . 概述 因为前段时间电脑坏了,导致代码遗失,踌躇满志马上上线的平台产品付之东流,现在熬夜在写代码希望能尽快推出企业正常使用的平台产品,而这次把代码开源,一是让大家对surging 使用有个深入的 ...
- [VS Code扩展]写一个代码片段管理插件(二):功能实现
@ 目录 创建和插入代码片段 代码片段列表 代码片段预览 代码片段编辑 自定义映射 默认映射 自动完成 项目地址 创建和插入代码片段 VS Code扩展提供了数据存储,其中globalState是使用 ...
- 短视频SDK 视频编辑SDK AE模版SDK 人体抠图SDK 绿幕抠图SDK
优势: 快速接入免费试用名称: 短视频SDK品牌: 蓝松SDK特色: 一站式视音频解决方案 杭州蓝松科技有限公司,多年来一直专注于音视频领域核心技术的研发.核心研发团队掌握的行业领先技术,目前 ...
- 第三方软件测评实验室-CNAS
一家获得中国合格评定国家认可委员会CNAS认证资质的第三方软件测评机构,能够提供以下专业服务 1. 登记测试报告:用于政府项目申报.高新认证.创新产品认定.首版次申报.招投标和报奖. 2. 信息系统验 ...
- echarts x轴下绘制表
效果图: 把下面代码复制到官网实例的js代码编辑中即可预览( 附连接:Examples - Apache ECharts) let map = { 销售单价: [2200.0,4000.9,700.0 ...
- XeLaTeX 无法编译含有经过 pdfcrop 裁剪的 PDF 文件的文档
今天在写 LaTeX 文档时踩了个大坑,我在文档里插入了一个 PDF 图片之后文档无法编译了. 于是我去掉多余代码,做了一个最小工作示例: \documentclass{article} \usepa ...
- LaTeX 三种短横线的区别
在 LaTeX 中,有三种基本的短横线,它们各自的长度和用法都有所不同.这三种短横线分别是连字符.短划线(或数字短横)和长划线.下面是它们的具体描述和用法: 连字符 (Hyphen, '-') 用法: ...
- 【FFmpeg】之Mac系统爬取所有M3U8视频下载方法
前言 由于有的网站不允许下载视频,到了有效期就不能看了,但是我想以后反复看,怎么办呢? 前提准备 操作系统:Mac 浏览器:谷歌浏览器 抓取m3u8工具:猫爪 视频处理工具:ffmpeg 需要安装工具 ...
- Python 项目及依赖管理工具技术选型
Python 项目及依赖管理工具,类似于 Java 中的 Maven 与 Node 中的 npm + webpack,在开发和维护项目时起着重要的作用.使用适当的依赖管理工具可以显著提高开发效率,减少 ...
- 计算机图形学(第四版) PDF 中文版
目录 图书介绍 下载地址 图书介绍 <计算机图形学(第四版)>是2014年电子工业出版社出版的图书,作者是Donald Hearn.M. Pauline Baker.Warren R. C ...