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)才能 ...
随机推荐
- [COCI2013-2014#6] KRUŽNICE 题解
前言 题目链接:洛谷. 题目分析 显然,手模样例发现答案分为以下几个贡献: 所有圆外面的那个大平面,贡献为 \(1\). 每个圆至少被分成一部分,贡献为 \(n\). 如果有一个圆被"拦腰截 ...
- Apache SeaTunnel社区5月月报更新!
各位热爱 SeaTunnel 的小伙伴们,社区 5 月份月报来啦! SeaTunnel 正在迅猛发展,积极投入社区项目建设的小伙伴将促进SeaTunnel不断提升数据同步的高可扩展性.高性能及高可靠性 ...
- SMU Spring 2023 Contest Round 5(2023 (ICPC) Jiangxi Provincial Contest -- Official Contest)
题目链接 Problem A. Drill Wood to Make Fire S * V >= n即可 #include<bits/stdc++.h> #define int lo ...
- 手把手教你ubuntu下移植MJPG-streamer
一.嵌入式视频图像开源库 在嵌入式系统中,常用的视频图像处理开源系统有:luvcview.cheese.motion.mjpg-streamer或者ffmpeg,其中: • luvcview: 基于V ...
- 从0实现基于Linux socket聊天室-多线程服务器模型-1
前言 Socket在实际系统程序开发当中,应用非常广泛,也非常重要.实际应用中服务器经常需要支持多个客户端连接,实现高并发服务器模型显得尤为重要.高并发服务器从简单的循环服务器模型处理少量网络并发请求 ...
- 金融、支付行业的开发者不得不知道的float、double计算误差问题
为什么浮点数 float 或 double 运算的时候会有精度丢失的风险呢? <阿里巴巴 Java 开发手册>中提到:"浮点数之间的等值判断,基本数据类型不能用 == 来比较,包 ...
- 关于centos7下所有指令失效
起因: 疑似宝塔更新修复后,本地所有环境变量集体不生效 问题环境 xshell环境下ssh连接 问题描述: - bash: xxx not fund - 环境变量无法保存 - 所有的保存方式都是临时生 ...
- 基于PaddleNLP信息抽取,uie微调打造自己专属的信息抽取模型
基于PaddleNLP信息抽取,uie微调打造自己专属的信息抽取模型 UIE模型简介 UIE优势 应用示例 UIE开箱即用 UIE适用抽取示例 命名实体识别(Named Entity Recognit ...
- 【YashanDB知识库】用户密码带@字符时exp和imp无法使用
[问题分类]数据导入导出 [关键字]YAS-00404.数据导入导出.密码.特殊字符@.exp.imp [问题描述] 当用户密码带@字符时,使用exp和imp导入导出数据,使用转义符仍然出现报错 且y ...
- ZEGO 即构科技首发适配鸿蒙系统的 Express SDK 1.0 版本
2019年8月,华为在开发者大会上正式发布鸿蒙系统. HarmonyOS 鸿蒙系统是一款"面向未来".面向全场景(移动办公.运动健康.社交通信.媒体娱乐等)的分布式操作系统.在 ...