最近,在使用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机制的更多相关文章

  1. Rust语言:安全地并发

    http://www.csdn.net/article/2014-02-26/2818556-Rust http://www.zhihu.com/question/20032903 Rust是近两年M ...

  2. 半个月使用rust语言的体验

    从第一次下载rust语言的编译器到今天刚好第14天. 简单说一下对这个语言的感觉吧. 一.性能 把以前用java写的一个中文地址切分的算法,用rust重新实现了一下(https://github.co ...

  3. Rust到底值不值得学--Rust对比、特色和理念

    前言 其实我一直弄不明白一点,那就是计算机技术的发展,是让这个世界变得简单了,还是变得更复杂了. 当然这只是一个玩笑,可别把这个问题当真. 然而对于IT从业者来说,这可不是一个玩笑.几乎每一次的技术发 ...

  4. Rust入坑指南:万物初始

    有没有同学记得我们一起挖了多少个坑?嗯-其实我自己也不记得了,今天我们再来挖一个特殊的坑,这个坑可以说是挖到根源了--元编程. 元编程是编程领域的一个重要概念,它允许程序将代码作为数据,在运行时对代码 ...

  5. the rust book 的简单入门笔记

    rust learning day 1 (2021/05/27) 学了常量,变量,数据类型,控制流,所有权 char 的宽度是4字节,一个 unicode 的宽度 控制流条件都不要括号 rust 中的 ...

  6. Rust所有权及引用

    Rust 所有权和借用 Rust之所以可以成为万众瞩目的语言, 就是因为其内存安全性. 在以往内存安全几乎全都是通过GC的方式实现, 但是GC会引来性能.CPU以及Stop The World等问题, ...

  7. 最强肉坦:RUST多线程

    Rust最近非常火,作为coder要早学早享受.本篇作为该博客第一篇学习Rust语言的文章,将通过一个在其他语言都比较常见的例子作为线索,引出Rust的一些重要理念或者说特性.这些特性都是令人心驰神往 ...

  8. Rust实战系列-基本语法

    本文是<Rust in action>学习总结系列的第二部分,更多内容请看已发布文章: 一.Rust实战系列-Rust介绍 " 主要介绍 Rust 的语法.基本类型和数据结构,通 ...

  9. 学习Rust第一天 Rust语言特点

    学习Rust之前,我觉得应该首先了解Rust语言的设计目的是什么?为什么会诞生这门语言?这门语言和其他的语言有什么不同. Rust语言的设计特点 高性能:rust拥有和C++相近的性能表现,所以在嵌入 ...

  10. Rust借用机制的理解分析

    Rust初学者大多会遇到这样的问题: 为什么同一资源不可被同时可变借用和不可变借用? 为什么Rc一定只能是只读的,一定要配合std::cell系列(Cell,RefCell,UnsafeCell)才能 ...

随机推荐

  1. 基于surging的产品项目-木舟开源了!

    一 . 概述 因为前段时间电脑坏了,导致代码遗失,踌躇满志马上上线的平台产品付之东流,现在熬夜在写代码希望能尽快推出企业正常使用的平台产品,而这次把代码开源,一是让大家对surging 使用有个深入的 ...

  2. [VS Code扩展]写一个代码片段管理插件(二):功能实现

    @ 目录 创建和插入代码片段 代码片段列表 代码片段预览 代码片段编辑 自定义映射 默认映射 自动完成 项目地址 创建和插入代码片段 VS Code扩展提供了数据存储,其中globalState是使用 ...

  3. 短视频SDK 视频编辑SDK AE模版SDK 人体抠图SDK 绿幕抠图SDK

    优势:  快速接入免费试用名称:  短视频SDK品牌:  蓝松SDK特色:  一站式视音频解决方案 杭州蓝松科技有限公司,多年来一直专注于音视频领域核心技术的研发.核心研发团队掌握的行业领先技术,目前 ...

  4. 第三方软件测评实验室-CNAS

    一家获得中国合格评定国家认可委员会CNAS认证资质的第三方软件测评机构,能够提供以下专业服务 1. 登记测试报告:用于政府项目申报.高新认证.创新产品认定.首版次申报.招投标和报奖. 2. 信息系统验 ...

  5. echarts x轴下绘制表

    效果图: 把下面代码复制到官网实例的js代码编辑中即可预览( 附连接:Examples - Apache ECharts) let map = { 销售单价: [2200.0,4000.9,700.0 ...

  6. XeLaTeX 无法编译含有经过 pdfcrop 裁剪的 PDF 文件的文档

    今天在写 LaTeX 文档时踩了个大坑,我在文档里插入了一个 PDF 图片之后文档无法编译了. 于是我去掉多余代码,做了一个最小工作示例: \documentclass{article} \usepa ...

  7. LaTeX 三种短横线的区别

    在 LaTeX 中,有三种基本的短横线,它们各自的长度和用法都有所不同.这三种短横线分别是连字符.短划线(或数字短横)和长划线.下面是它们的具体描述和用法: 连字符 (Hyphen, '-') 用法: ...

  8. 【FFmpeg】之Mac系统爬取所有M3U8视频下载方法

    前言 由于有的网站不允许下载视频,到了有效期就不能看了,但是我想以后反复看,怎么办呢? 前提准备 操作系统:Mac 浏览器:谷歌浏览器 抓取m3u8工具:猫爪 视频处理工具:ffmpeg 需要安装工具 ...

  9. Python 项目及依赖管理工具技术选型

    Python 项目及依赖管理工具,类似于 Java 中的 Maven 与 Node 中的 npm + webpack,在开发和维护项目时起着重要的作用.使用适当的依赖管理工具可以显著提高开发效率,减少 ...

  10. 计算机图形学(第四版) PDF 中文版

    目录 图书介绍 下载地址 图书介绍 <计算机图形学(第四版)>是2014年电子工业出版社出版的图书,作者是Donald Hearn.M. Pauline Baker.Warren R. C ...