- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
最近,在使用Rust时遇到了Reborrow的概念,记录下来以备以后参考.
起因准备对数据进行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的机制可以实现上面的需求.
借用(Borrow)是Rust中的一个重要概念,它是允许代码访问某个值而不获取其所有权的一种机制.
而Reborrow则是指在一个已存在的借用基础上创建一个新的借用, 。
这个新的借用可以是不可变的,也可以是可变的(前提是原始借用是可变的,并且没有其他借用存在).
总的来说,Reborrow通过在已存在的借用上创建新的借用,从而扩展引用的生命周期并在更广泛的作用域内安全地访问值.
下面通过实践来检验对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的Reborrow机制的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一名优秀的程序员,十分优秀!