Recently, the use ofRust
luckilyReborrow
concepts, recorded for future reference.
1. Causes
Cause prepares the data forMin-Max
Normalized processing, that is, mapping a range of data to a new range.
First, the data needs to be traversed to find out where themaximum valuescap (a poem)minimum value, and then change the values of the original data set by using the formula.
Min-Max
Formula: Normalized value = (original value - minimum value) / (maximum value - minimum value)
The simplified code is as follows:
fn main() {
let mut values = vec![10.5, 22.3, 103.5, 45.75];
let v = &mut values;
println!("raw data: {:#?}", 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!("commencementMin-MaxStandardized processing...");
for n in v {
*n = (*n - min) / (max - min);
}
println!("Post-processed data: {:#?}", values);
}
It runs with the following error:
error[E0382]: use of moved value: `v`
--> src/: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
|
probablyLine 9(math.) ergodicv
of finding the maximum and minimum values whenVariable borrowing vthat the right to use it has been transferred.
thus inLine 22miss (feel wistful about the absence of sb. or sth)Iterate over v againError when going to change the value.
Here, becauseVector
Not realizedCopy Trait
, so it's mutable borrowing on the first traversal due to an implicit call to the.into_iter()
, ownership is transferred.
If you want to traverse theVector
, you can use its immutable borrowing, such as defining thelet v = &values;
Then it is possible to traverse multiple timesv
Because of the immutable borrowing are realizedCopy Trait
。
But the second time I traversedv
when it is used, it is also necessary to modify the value in it, so it must be defined as a variable borrowinglet v = &mut values;
By searching for information, it was found thatReborrow
mechanism can fulfill the above requirements.
2. The concept of reborrow
Borrowing (Borrow
) isRust
It is an important concept in the concept of a mechanism that allows code to access a value without taking ownership of it.
(indicates contrast)Reborrow
then the creation of a new borrowing based on a pre-existing borrowing.
This new borrowing can be immutable or mutable (provided that the original borrowing is mutable and no other borrowing exists).
Overall.Reborrow
Extend the lifecycle of references and securely access values in a wider scope by creating new borrows on top of existing ones.
3. Solutions
The following is a practical test for theReborrow
Conceptual understanding.
Returning to the problem encountered in the first section, the solution is to traverse the first time thev
Time (Line 9), don't transfer ownership.
Thus, the second traversal ofv
(Line 22) would not have reported the"value used here after move"
The error.
according toReborrow
The mechanism that we have inLine 9canReborrow
Variable borrowingv
The transfer was made in such a way that it was re-borrowed.v
Instead ofv
itself.
The method of change is simple.Line 9change intofor n in &*v {
That's all, that is, firstReduction v(*v
), and thenReborrow
(&*v
)。
Modify and run the code again:
$ cargo run
Raw data: [
10.5,
22.3,
10.5, 22.3, 103.5,
45.75.
max is 103.5]
max is 103.5
min is 10.5
Start Min-Max normalization...
Processed data: [
0.0,
0.12688172043010754, [
1.0, 0.379032258080754
0.3790322580645161, ]
]
values
The data in the
Note that this is where thev
Reborrow into an immutable borrowing&*v
Because I didn't need to change it the first time I traversed it.v
。
if you want tov
Reborrow into a variable borrowing can be written as:&mut *v
。